开发者

How do I create a Status Icon / System Tray Icon with custom text and transparent background using Python and GTK?

开发者 https://www.devze.com 2023-01-03 18:43 出处:网络
Here is the code that I have so far to define the icon: icon_bg = gtk.gdk.pixbuf_new_from_file(\'gmail.png\')

Here is the code that I have so far to define the icon:

icon_bg = gtk.gdk.pixbuf_new_from_file('gmail.png')
w, h = icon_bg.get_width(), icon_bg.get_height()
cmap = gtk.gdk.Colormap(gtk.gdk.visual_get_system(), False)

drawable = gtk.gdk.Pixmap(None, w, h, 24)
drawable.set_colormap = cmap
gc = drawable.new_gc()
drawable.draw_pixbuf(gc, icon_bg, 0, 0, 0, 0, w, h)

drawn_icon = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, w, h)
drawn_icon.get_from_drawable(drawable, cmap, 0, 0, 0, 0, w, h)
icon = gtk.status_icon_new_from_pixbuf(drawn_icon)

This works to get the png into the icon, but falls short in two areas. First, transparency is not working. If I use a 22x22 png with transparent background and the image centered, I end up with sections of other active icons showing up inside of mine, like this:

http://i237.photobucket.com/albums/ff311/Raugturi/22x22_image_with_transparency.png

The icon it choose to steal from is somewhat random. Sometimes it's part of the dropbox icon, others the NetworkManager Applet.

If I instead use this code:

icon_bg = gtk.gdk.pixbuf_new_from_file('gmail.png')
w, h = icon_bg.get_width(), icon_bg.get_height()
cmap = gtk.gdk.Colormap(gtk.gdk.visual_get_system(), False)

drawable = gtk.gdk.Pixmap(None, w, h, 24)
drawable.set_colormap = cmap
gc = drawable.new_gc()
drawable.draw_pixbuf(gc, icon_bg, 0, 0, 0, 0, w, h)

drawn_icon = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 22, 22)
drawn_icon.get_from_drawable(drawable, cmap, 0, 0, 3, 6, w, h)
icon = gtk.status_icon_new_from_pixbuf(drawn_icon)

And an image that is only 16x11 with the transparent edges removed, what I end up with is this:

http://i237.photobucket.com/albums/ff311/Raugturi/16x11_image_positioned_in_middle.png

So how do I end up with a transparent block like the 1st one that doesn't pull in stuff from other icons?

As for the second problem, I need the ability to write on the image before converting it to the icon. I tried using draw_glyphs and it told me I should be using Pango layout/context instead. Unfortunately all the Pango tutorials I could find deal with actual windows, not the status icon. Is there a good tutorial out there for Pango that would apply to this issue (and also maybe have at least some explanation of how to tell it what font to use as all of them that I found seem to lack this and it won't write anything without it).

Note: Sorry for the lack of actual images and only one working link, apparently this is a spam prevention feature due to my lack of 开发者_JAVA百科reputation.


I wrote this tool (in C, but it is designed to be a separate process) to work with any language (perl, python, tcl, lua, c, c++, bash, ksh,...) Just start it up with any number of icons with tooltips and right and left click commands (only limited by the size of the tray). Then just change your icon as needed. The easiest way to handle the icons is via SVG, since it is really easy to include other images (including png) and quickly define text or even complex (or simple) shapes using pre-formatted commands.

#include <sys/inotify.h>
#include <gtk/gtk.h>
#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

void leftclick(GtkStatusIcon *si, gpointer s) {
    popen(s,"r"); /* exec s */
}

void rightclick(GtkStatusIcon *si, guint b,guint a_t, gpointer s) {
    popen(s,"r");
}

void refresh(gpointer si, gint fd, GdkInputCondition c) {
    char buffer[EVENT_BUF_LEN];
    read( fd, buffer, EVENT_BUF_LEN ); /* we are just clearing it & do not care what event type */
    gtk_status_icon_set_from_file(si,gtk_status_icon_get_title(si)); /* redraws */
}

int main(int argc, char *argv[]) {
    GtkStatusIcon *si; int i=1, watch, fd;
    gtk_init (&argc, &argv); /* loop through icon, tooltip, click messages */
    while (i<argc) {    fd = inotify_init(); /* get file descriptor to write on if image changes */
        si = gtk_status_icon_new_from_file(argv[i]); /* get a status icon widget */
        gtk_status_icon_set_title(si,argv[i]); /* hack to store the image path */
        watch = inotify_add_watch( fd, argv[i++], IN_CREATE | IN_MODIFY | IN_MOVED_FROM );
        gdk_input_add( fd, GDK_INPUT_READ, refresh, si ); /* inotify fd is ready for reading, refresh */
        gtk_status_icon_set_tooltip_text(si,argv[i++]);
        g_signal_connect(G_OBJECT(si), "activate", G_CALLBACK(leftclick), (gpointer) argv[i++]);
        g_signal_connect(G_OBJECT(si), "popup-menu", G_CALLBACK(rightclick), (gpointer) argv[i++]);
    }
    gtk_main();
}


Is there a reason you can't just use gtk.StatusIcon.set_from_file? It works fine with transparent images.

As for your second question, I highly doubt that it is possible to use pango on a gtk.StatusIcon.
Why do you need to write text on the icon?

0

精彩评论

暂无评论...
验证码 换一张
取 消