引用自:
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