如何使 Gtk+ 窗口背景透明? [英] How to make Gtk+ window background transparent?

查看:72
本文介绍了如何使 Gtk+ 窗口背景透明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让 Gtk+ 窗口的背景透明,以便只有窗口中的小部件可见.我找到了一些教程:

I'd like to make the background of a Gtk+ window transparent so that only the widgets in the window are visible. I found a few tutorials:

http://mikehearn.wordpress.com/2006/03/26/gtk-windows-with-alpha-channels/

http://macslow.thepimp.net/?p=26

但他们似乎都在监听expose"事件,然后委托 Cairo 进行渲染.这意味着添加到窗口的其他小部件不会呈现(例如,我也尝试向窗口添加按钮).

But they both appear to listen to the "expose" event, and then delegate to Cairo to do the rendering. This means that other widgets added to the window are not rendered (for example, I've tried adding a button to the window as well).

我看到 GtkWidget 上有一个方法 modify-bg:http://library.gnome.org/devel/gtk/stable/GtkWidget.html#gtk-widget-modify-bg

I see that there's a method modify-bg on GtkWidget: http://library.gnome.org/devel/gtk/stable/GtkWidget.html#gtk-widget-modify-bg

但是,GdkColor 似乎不接受透明度参数:http://library.gnome.org/devel/gdk/stable/gdk-Colormaps-and-Colors.html

However, GdkColor does not appear to accept a parameter for transparency: http://library.gnome.org/devel/gdk/stable/gdk-Colormaps-and-Colors.html

我也尝试过 GtkWindow.set_opacity 方法,但这也设置了窗口内容的不透明度,这不是我想要的.

I've tried the GtkWindow.set_opacity method as well, but this sets the opacity for the window contents as well, which is not what I want.

如果有人能在这方面提供任何指导,我将不胜感激.

I'd appreciate any guidance anyone can provide in this.

推荐答案

我改了alphademo 示例来绘制一个按钮而不是红色圆圈.

I changed the alphademo example to draw a button instead of the red circle.

此应用程序在 400x400 透明窗口上绘制按钮.

This application draws the button on a 400x400 transparent window.

当您单击窗口时,应用程序会显示/隐藏标题栏.

When you click on the window the application shows/hides the title bar.

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

static void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer user_data);
static gboolean expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
static void clicked(GtkWindow *win, GdkEventButton *event, gpointer user_data);

int main(int argc, char **argv)
{
    gtk_init(&argc, &argv);

    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
    gtk_window_set_title(GTK_WINDOW(window), "Alpha Demo");
    g_signal_connect(G_OBJECT(window), "delete-event", gtk_main_quit, NULL);

    gtk_widget_set_app_paintable(window, TRUE);

    g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(expose), NULL);
    g_signal_connect(G_OBJECT(window), "screen-changed", G_CALLBACK(screen_changed), NULL);

    gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
    gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
    g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(clicked), NULL);

    GtkWidget* fixed_container = gtk_fixed_new();
    gtk_container_add(GTK_CONTAINER(window), fixed_container);
    GtkWidget* button = gtk_button_new_with_label("button1");
    gtk_widget_set_size_request(button, 100, 100);
    gtk_container_add(GTK_CONTAINER(fixed_container), button);

    screen_changed(window, NULL, NULL);

    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}


gboolean supports_alpha = FALSE;
static void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer userdata)
{
    /* To check if the display supports alpha channels, get the colormap */
    GdkScreen *screen = gtk_widget_get_screen(widget);
    GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);

    if (!colormap)
    {
        printf("Your screen does not support alpha channels!
");
        colormap = gdk_screen_get_rgb_colormap(screen);
        supports_alpha = FALSE;
    }
    else
    {
        printf("Your screen supports alpha channels!
");
        supports_alpha = TRUE;
    }

    gtk_widget_set_colormap(widget, colormap);
}

static gboolean expose(GtkWidget *widget, GdkEventExpose *event, gpointer userdata)
{
   cairo_t *cr = gdk_cairo_create(widget->window);

    if (supports_alpha)
        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */
    else
        cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */

    /* draw the background */
    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
    cairo_paint (cr);

    cairo_destroy(cr);

    return FALSE;
}

static void clicked(GtkWindow *win, GdkEventButton *event, gpointer user_data)
{
    /* toggle window manager frames */
    gtk_window_set_decorated(win, !gtk_window_get_decorated(win));
}

在 Ubuntu 10.04 上编译:

Compiled on Ubuntu 10.04:

gcc alpha.c -o alpha -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -lgtk-x11-2.0

这篇关于如何使 Gtk+ 窗口背景透明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆