热门标签 | 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;
}

运行结果如下:


推荐阅读
  • ListView简单使用
    先上效果:主要实现了Listview的绑定和点击事件。项目资源结构如下:先创建一个动物类,用来装载数据:Animal类如下:packagecom.example.simplelis ... [详细]
  • 本文探讨了在Java中实现系统托盘最小化的两种方法:使用SWT库和JDK6自带的功能。通过这两种方式,开发者可以创建跨平台的应用程序,使窗口能够最小化到系统托盘,并提供丰富的交互功能。 ... [详细]
  • MQTT技术周报:硬件连接与协议解析
    本周开发笔记重点介绍了在新项目中使用MQTT协议进行硬件连接的技术细节,涵盖其特性、原理及实现步骤。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 掌握远程执行Linux脚本和命令的技巧
    本文将详细介绍如何利用Python的Paramiko库实现远程执行Linux脚本和命令,帮助读者快速掌握这一实用技能。通过具体的示例和详尽的解释,让初学者也能轻松上手。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 本文介绍如何使用布局文件在Android应用中排列多行TextView和Button,使其占据屏幕的特定比例,并提供示例代码以帮助理解和实现。 ... [详细]
  • 在 Flutter 开发过程中,开发者经常会遇到 Widget 构造函数中的可选参数 Key。对于初学者来说,理解 Key 的作用和使用场景可能是一个挑战。本文将详细探讨 Key 的概念及其应用场景,并通过实例帮助你更好地掌握这一重要工具。 ... [详细]
  • 本文介绍了Android开发中Intent的基本概念及其在不同Activity之间的数据传递方式,详细展示了如何通过Intent实现Activity间的跳转和数据传输。 ... [详细]
  • 本文介绍如何使用 Android 的 Canvas 和 View 组件创建一个简单的绘图板应用程序,支持触摸绘画和保存图片功能。 ... [详细]
  • 在本教程中,我们将深入探讨如何使用 Python 构建游戏的主程序模块。通过逐步实现各个关键组件,最终完成一个功能完善的游戏界面。 ... [详细]
  • 在 Android 开发中,通过 Intent 启动 Activity 或 Service 时,可以使用 putExtra 方法传递数据。接收方可以通过 getIntent().getExtras() 获取这些数据。本文将介绍如何使用 RoboGuice 框架简化这一过程,特别是 @InjectExtra 注解的使用。 ... [详细]
  • 本文探讨了如何在Classic ASP中实现与PHP的hash_hmac('SHA256', $message, pack('H*', $secret))函数等效的哈希生成方法。通过分析不同实现方式及其产生的差异,提供了一种使用Microsoft .NET Framework的解决方案。 ... [详细]
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社区 版权所有