Chinaunix首页 | 论坛 | 博客
  • 博客访问: 191307
  • 博文数量: 49
  • 博客积分: 2065
  • 博客等级: 大尉
  • 技术积分: 413
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-08 17:04
文章分类

全部博文(49)

文章存档

2012年(2)

2010年(17)

2009年(30)

我的朋友

分类:

2009-09-18 10:28:04

Gtk透明窗口全攻略

      

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

 

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

2.  异形窗口

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

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

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

#include

 

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

 

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

 

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;

}

阅读(4200) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~