热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

GTK+2:实现透明背景下的小部件叠加绘制

本文介绍了如何在GTK+2中实现透明背景下的小部件叠加绘制,类似于GTK3中的GtkOverlay功能。

由于项目需求,我必须使用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;
}

运行结果如下:


推荐阅读
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • 在尝试用另一台电脑的MySQL文件替换本地D:\xampp\mysql目录后,MySQL服务无法启动。错误提示显示MySQL意外关闭,可能是由于端口冲突、依赖缺失、权限问题或崩溃等原因引起。 ... [详细]
  • 三星W799在2011年的表现堪称经典,以其独特的双屏设计和强大的功能引领了双模手机的潮流。本文详细介绍其配置、功能及锁屏设置。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 本文详细介绍了中央电视台电影频道的节目预告,并通过专业工具分析了其加载方式,确保用户能够获取最准确的电视节目信息。 ... [详细]
  • 本文探讨了在Java中实现系统托盘最小化的两种方法:使用SWT库和JDK6自带的功能。通过这两种方式,开发者可以创建跨平台的应用程序,使窗口能够最小化到系统托盘,并提供丰富的交互功能。 ... [详细]
  • 在 Flutter 开发过程中,开发者经常会遇到 Widget 构造函数中的可选参数 Key。对于初学者来说,理解 Key 的作用和使用场景可能是一个挑战。本文将详细探讨 Key 的概念及其应用场景,并通过实例帮助你更好地掌握这一重要工具。 ... [详细]
  • 本文介绍了Android开发中Intent的基本概念及其在不同Activity之间的数据传递方式,详细展示了如何通过Intent实现Activity间的跳转和数据传输。 ... [详细]
  • 本文深入探讨了HTTP请求和响应对象的使用,详细介绍了如何通过响应对象向客户端发送数据、处理中文乱码问题以及常见的HTTP状态码。此外,还涵盖了文件下载、请求重定向、请求转发等高级功能。 ... [详细]
  • 本文介绍如何使用 Android 的 Canvas 和 View 组件创建一个简单的绘图板应用程序,支持触摸绘画和保存图片功能。 ... [详细]
  • Qt QTableView 内嵌控件的实现方法
    本文详细介绍了在 Qt QTableView 中嵌入控件的多种方法,包括使用 QItemDelegate、setIndexWidget 和 setIndexWidget 结合布局管理器。每种方法都有其适用场景和优缺点。 ... [详细]
author-avatar
时间熔金-岁月铅华_758
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有