Gtk透明窗口全攻略

Gtk透明窗口全攻略引用自:

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

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


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值