Gtk透明窗口全攻略

时间:2024-04-02 16:10:24

引用自:

http://xy0811.spaces.live.com/blog/cns!F8AECD2A067A6B17!1256.entry

Gtk透明窗口全攻略

 Gtk透明窗口全攻略      

如图所示,左边是普通的 ubuntu 桌面,右边是我建立的三个 gtk 特殊窗口,其中包含了:异形窗口(上),透明窗体(中),不同区域不同透明度的窗口(下)。基本包括了各种特殊窗口的需求,而复杂程度和依赖工具又各有不同,下面是实现的代码及说明

 

1.   环境说明
ubuntu 8.04
系统,安装 glib-dev cairo

2.   异形窗口

a)          原理
异形窗口利用蒙板( mask )实现,蒙板的数据从图片获得,每一点只有透明和不透明两种状态,不透明区域显示该窗口的背景,透明区域显示其后桌面或其它应用

b)         效果
可实现异形窗口,但不支持半透明,所以弧形边缘看起来不够平滑。

c)         依赖
gtk
的基本功能,一般 gtk 都可以支持

#include <gtk/gtk.h>

 

int main(int argc, char *argv[])

{

   GtkWidget *window = NULL;

   GdkPixbuf *pixbuf = NULL;

   GdkBitmap *bitmap = NULL;

   GdkPixmap *pixmap = NULL;

 

   gtk_init(&argc, &argv);

 

   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

   gtk_window_set_decorated(GTK_WINDOW(window), FALSE);       // 设置无边框

   gtk_widget_set_app_paintable(window, TRUE);

   gtk_widget_realize(window);

 

   pixbuf = gdk_pixbuf_new_from_file("demo1.png", NULL);       // gdk 函数读取 png 文件

   gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, &bitmap, 128);    // alpha 小于 128 认为透明

   gtk_widget_shape_combine_mask(window, bitmap, 0, 0);          // 设置透明蒙板

   gdk_window_set_back_pixmap(window->window, pixmap, FALSE);          // 设置窗口背景

 

   g_object_unref(pixbuf);

   g_object_unref(bitmap);

   g_object_unref(pixmap);

 

   gtk_widget_show_all(window);

   gtk_main();

   return TRUE;

}

3.   透明窗体

a)          原理
使用函数 gtk_window_set_opacity 设置整个窗体的透明度

b)         效果
窗体各处透明度相同

c)         依赖
gtk_window_set_opacity
函数只能在 gtk-2.12 以上版本中使用

#include <gtk/gtk.h>

 

int main(int argc, char *argv[])

{

   GtkWidget *window = NULL;

 

   gtk_init(&argc, &argv);

 

   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

   gtk_window_set_opacity(GTK_WINDOW(window), 0.7);       // 设置透明度函数

 

   gtk_widget_show_all(window);

   gtk_main();

   return TRUE;

}

4.   不同区域不同透明度的窗口

a)          原理
利用 cairo 库与 gtk 相结合,在曝光函数中用 cairo 向窗口区域绘图,每一点可以设置不同的透明度,但相对复杂,依赖更多的库

b)         效果
可设置窗口各个点不同的透明度,过度平滑,效果最好

c)         依赖
gtk
及相应版本的 cairo

#include <gtk/gtk.h>

 

cairo_surface_t *image = NULL;

 

static gboolean on_window_expose_event(GtkWidget * widget,             // 曝光事件

     GdkEventExpose * event, gpointer data)

{

   cairo_t *cr;

 

   cr = gdk_cairo_create(widget->window);

   cairo_set_source_surface(cr, image, 0, 0);

   cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);          // 重要

   cairo_paint(cr);   // 绘图

   cairo_destroy(cr);

   return FALSE;

}

 

gint main(gint argc, gchar ** argv)

{

   GtkWidget *window;

   GdkScreen *screen;

   GdkColormap *colormap;

 

   gtk_init(&argc, &argv);

 

   image = cairo_image_surface_create_from_png("demo3.png");             // cairo 函数读取 png 文件

   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

   gtk_window_set_decorated(GTK_WINDOW(window), FALSE);       // 设置无边框

   gtk_widget_set_app_paintable(window, TRUE);

   gtk_window_resize(GTK_WINDOW(window), 250, 250);

   g_signal_connect(G_OBJECT(window), "expose-event",

              G_CALLBACK(on_window_expose_event), NULL);

 

   screen = gtk_widget_get_screen(window);       // 重要

   colormap = gdk_screen_get_rgba_colormap(screen);

   gtk_widget_set_colormap(window, colormap);

 

   gtk_widget_show_all(window);

   gtk_main();

   return TRUE;

}

5.   参考
http://cid-f8aecd2a067a6b17.skydrive.live.com/browse.aspx/.Public?uc=1&isFromRichUpload=1
示例代码为 gtk_demo.tgz