c - 如何使 Gtk+ 窗口背景透明?

标签 c background window gtk transparent

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

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

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

但它们似乎都在监听“暴露”事件,然后委托(delegate)给 Cairo 进行渲染。这意味着添加到窗口的其他小部件不会呈现(例如,我也尝试将按钮添加到窗口)。

我看到 GtkWidget 上有一个方法 modify-bg: 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

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

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

最佳答案

我更改了 alphademo例如绘制一个按钮而不是红色圆圈。

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

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

#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!\n");
        colormap = gdk_screen_get_rgb_colormap(screen);
        supports_alpha = FALSE;
    }
    else
    {
        printf("Your screen supports alpha channels!\n");
        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 上编译:

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

关于c - 如何使 Gtk+ 窗口背景透明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3908565/

相关文章:

html - 如果图像大于 div,则强制占用 div

ios - NSURLSession 和后台流上传

html - 位置 :relative breaking background-clip: text

c - 需要 MPI 通信器创建数据包的逻辑是什么?

c - Execvp 与 "ls -l | wc"一起工作,但因“ls -l|wc”而失败

c - 如果我尝试从 Channel 调用字符串数据,则会出现错误结果

javascript - 使用亚马逊付款 在弹出窗口中打开

android - 暗淡的背景,就像显示对话框时一样

c - 当写入发生在多个目录中时,磁盘写入性能会下降

c - 为什么不评估预增量