作者:时间熔金-岁月铅华_758 | 来源:互联网 | 2024-11-16 21:57
由于项目需求,我必须使用Gtk+2,因此请不要建议切换到版本3或4。
我的目标是创建类似Gtk3中的GtkOverlay
功能,即在一个透明背景上绘制其他小部件。
我的初步想法是使用GtkFixed
来放置普通的子小部件,然后在其上方使用一个GtkEventBox
,并在支持的情况下将其背景设置为透明,并连接其暴露事件以实现透明效果。
尽管我取得了一些进展,但结果并不理想。虽然事件框变得半透明,但它显示的是窗口下方的内容,而不是下面的小部件。
以下是目前的代码(请原谅代码的混乱):
#include
GtkWidget *window;
GtkWidget *button;
GtkWidget *vbox;
GtkWidget *fixed;
GtkWidget *event_overlay;
gboolean supports_alpha = FALSE;
static void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer userdata)
{
GdkScreen *screen = gtk_widget_get_screen(widget);
GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);
if (!colormap) {
printf("您的屏幕不支持Alpha通道!\n");
colormap = gdk_screen_get_rgb_colormap(screen);
supports_alpha = FALSE;
} else {
printf("您的屏幕支持Alpha通道!\n");
supports_alpha = TRUE;
}
gtk_widget_set_colormap(widget, colormap);
}
static gboolean exposed(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget));
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.5); // 透明
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_paint(cr);
cairo_destroy(cr);
return TRUE;
}
static void hello(GtkWidget *widget, gpointer data)
{
gtk_fixed_put(GTK_FIXED(fixed), event_overlay, 100, 100);
}
static void destroy(GtkWidget *widget, gpointer data)
{
gtk_main_quit();
}
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "destroy", G_CALLBACK(destroy), NULL);
button = gtk_button_new_with_label("Hello World");
g_signal_connect(button, "clicked", G_CALLBACK(hello), NULL);
vbox = gtk_vbox_new(TRUE, 5);
gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
fixed = gtk_fixed_new();
gtk_fixed_set_has_window(GTK_FIXED(fixed), TRUE);
gtk_widget_set_size_request(button, 500, 500);
gtk_fixed_put(GTK_FIXED(fixed), vbox, 0, 0);
event_overlay = gtk_event_box_new();
gtk_widget_set_size_request(event_overlay, 500, 500);
g_signal_connect(event_overlay, "expose-event", G_CALLBACK(exposed), NULL);
g_signal_connect(G_OBJECT(window), "screen-changed", G_CALLBACK(screen_changed), NULL);
gtk_widget_set_app_paintable(window, TRUE);
gtk_container_add(GTK_CONTAINER(window), fixed);
screen_changed(window, NULL, NULL);
gtk_widget_show_all(window);
gtk_widget_show(event_overlay);
gtk_main();
return 0;
}
运行结果如下: