如圖所示,左邊是普通的ubuntu桌面,右邊是我建立的三個gtk特殊窗口,其中包含了:異形窗口(上),透明窗體(中),不同區域不同透明度的窗口(下)。基本包括了各種特殊窗口的需求,而複雜程度和依賴工具又各有不同,下面是實現的代碼及說明
1. 環境說明
ubuntu 8.04系統,安裝glib-dev和cairo包
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;
}
5. 參考
http://cid-f8aecd2a067a6b17.skydrive.live.com/browse.aspx/.Public?uc=1&isFromRichUpload=1
示例代碼為gtk_demo.tgz
沒有留言:
張貼留言