用GTK实现的一个背景透明窗口,求帮忙优化

软件和网站开发以及相关技术探讨
回复
dalin888
帖子: 1
注册时间: 2014-05-22 20:48
系统: ubuntu
送出感谢: 0
接收感谢: 0

用GTK实现的一个背景透明窗口,求帮忙优化

#1

帖子 dalin888 » 2014-05-22 20:54

刚接触gtk不久,需要用gtk3.0,画一个背景透明的窗口(即:在窗口中放一个图片,则只显示该图片,不显示底层窗口等)
网上由用gtk2.0写的比较好的例子,但是我这里需要用3.0来写。
目前样子是出来了,但是显示的图片和原图片有差距(显示的效果编译有毛刺,且颜色略有差异,后面会贴图),求高手提供优化方法。
下面是我的程序:

代码: 全选

#include <gtk/gtk.h>
#include <gdk/gdk.h>

int main(int argc, char *argv[]){
        GtkWidget *window = NULL;
        GdkPixbuf *pixbuf = 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("floatbg.png", NULL);

        cairo_surface_t *img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 
                        gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
        cairo_t *cr = cairo_create(img);
        gdk_cairo_set_source_pixbuf(cr, pixbuf,0,0);
        cairo_paint(cr);
        cairo_region_t *mask = gdk_cairo_region_create_from_surface(img);
        gtk_widget_shape_combine_region(window, mask);
        
        cairo_region_destroy(mask);
        cairo_surface_destroy(img);
        g_object_unref(pixbuf);
        
        gtk_widget_show_all(window);
        gtk_main();
        return TRUE;
}
编译:
gcc image.c -o image `pkg-config --cflags --libs gtk+-3.0` -export-dynamic

上一张图tt1是执行./image后的效果,下一张图tt2是原图效果(一个椭圆按钮,背景透明):
tt1:
图片

tt2:
图片
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙
送出感谢: 4 次
接收感谢: 256 次

Re: 用GTK实现的一个背景透明窗口,求帮忙优化

#2

帖子 eexpress » 2014-05-23 8:42

pixbuf是gtk2的套路。gtk3,你至少要使用cairo来渲染了。

给你一个例子

代码: 全选

▶ cat showpng.vala 
using Gtk;
using Cairo;

class ShowPNG : Gtk.Window {

	public ShowPNG(string fimg) {
        title = "ShowPNG";
		skip_taskbar_hint = true;
        decorated = false;
        app_paintable = true;
		set_visual(this.get_screen().get_rgba_visual());
		set_opacity(1);
		stick();
		var img = new Cairo.ImageSurface.from_png (fimg);
		set_size_request(img.get_width(),img.get_height());
		var drawing_area = new DrawingArea ();
		drawing_area.draw.connect ((da,ctx) => {
				ctx.set_operator (Cairo.Operator.SOURCE);
				ctx.set_source_surface(img,0,0);
				ctx.paint ();
				return true;
				});
        add (drawing_area);

		drawing_area.add_events (Gdk.EventMask.BUTTON_PRESS_MASK);
		drawing_area.button_press_event.connect ((e) => {
				if(e.button == 1){
					begin_move_drag ((int) e.button, (int) e.x_root, (int) e.y_root, e.time);
				} else {Gtk.main_quit();}
				return true;
				});

		destroy.connect (Gtk.main_quit);
	}

	static int main (string[] args) {
		Gtk.init (ref args);
		string file= "/tmp/weather.png";
		if(args[1]!=null && args[1].has_suffix(".png")) file = args[1];
		var showpng = new ShowPNG(file);
		showpng.show_all ();
		Gtk.main ();
		return 0;
	}
}
● 鸣学
回复

回到 “软件/网站开发”