我如何真正制作GTK + 3 GtkLayout透明/绘制主题背景? [英] How do I really make a GTK+ 3 GtkLayout transparent/draw theme background?

查看:217
本文介绍了我如何真正制作GTK + 3 GtkLayout透明/绘制主题背景?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我创建里面什么也没有或是一个内部有GtkDrawingArea一个GtkWindow(或一个GtkScrolledWindow内)一个普通的GtkWindow,我得到的主题背景的窗口,为的 this picture

If I create a normal GtkWindow with nothing inside or a GtkWindow with a GtkDrawingArea inside (or that inside a GtkScrolledWindow), I get a window with the theme's background, as in this picture.

但是如果我使用GtkLayout,我会得到一个纯色背景的窗口,如此图

But if I use a GtkLayout, I get a window with a solid color background, as in this picture.

只有资源(包括我自己)可以找到迄今为止这个其他堆栈溢出问题,但是当我按照要求做的时候,我会得到完全黑色的背景,就像这张照片,就算我得到了GtkLayout的bin窗口开罗上下文。

The only resource anyone (myself included) could find so far was this other Stack Overflow question, but when I do what it says to do, I get a fully black background, like in this picture, even if I get a cairo context for the GtkLayout's bin window.

那么究竟如何我得到的GtkLayout是透明的,或者,如果这不是一个选项,以使用我的背景是什么?

So how exactly do I get the GtkLayout to be transparent, or if that's not an option, to use the theme's background?

虽然我使用GTK + 3.10运行,但我需要定位到GTK + 3.4,所以gtk_widget_set_opacity()将不起作用。在我的屏幕截图中显示的主题是gtk-oxygen主题;我正在使用KDE。

Though I am running with GTK+ 3.10, I need to target GTK+ 3.4, so gtk_widget_set_opacity() won't work. The theme shown in my screenshots is the gtk-oxygen theme; I am using KDE.

下面的示例程序。它有覆盖上述所有情况的选项。我还尝试了 draw()中的各种cairo调用的变体(注释掉某些部分,在设置 CLEAR ,不设置剪辑矩形等);那也没用。

Sample program below. It has options to cover all the cases I described above. I also tried variations of the various cairo calls in draw() (commenting some out, adding another alpha color selection after setting CLEAR, not setting a clip rect, etc.); that didn't work either.

谢谢!

Thanks!

/* pietro gagliardi - 7-8 april 2014 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define GDK_VERSION_MIN_REQUIRED GDK_VERSION_3_4
#define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_4
#include <gtk/gtk.h>

gboolean windowonly = FALSE;
gboolean drawingarea = FALSE;
gboolean viewport = FALSE;
gboolean drawsig = FALSE;
gboolean binwin = FALSE;

void parseargs(int argc, char *argv[])
{
    if (argc != 2 && argc != 3)
        goto usage;

#define extra(str) (argc == 3 && strcmp(argv[2], str) == 0)
#define noextra(cond) if (!(cond) && argc == 3) goto usage;
    if (strcmp(argv[1], "windowOnly") == 0) {
        noextra(FALSE);
        windowonly = TRUE;
        return;
    } else if (strcmp(argv[1], "drawingArea") == 0) {
        drawingarea = TRUE;
        viewport = extra("viewport");
        noextra(viewport);
        return;
    } else if (strcmp(argv[1], "layout") == 0) {
        binwin = extra("drawbin");
        drawsig = binwin || extra("draw");
        noextra(drawsig);
        return;
    }

usage:
    fprintf(stderr, "usage:\n");
    fprintf(stderr, "\t%s windowOnly\n", argv[0]);
    fprintf(stderr, "\t%s drawingArea [viewport]\n", argv[0]);
    fprintf(stderr, "\t%s layout [draw|drawbin]\n", argv[0]);
    exit(1);
}

gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer data)
{
    double x, y, w, h;

    if (binwin)
        cr = gdk_cairo_create(gtk_layout_get_bin_window((GtkLayout *) widget));

    cairo_clip_extents(cr, &x, &y, &w, &h);
    cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
    cairo_rectangle(cr, x, y, w, h);
    cairo_fill(cr);
    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
    cairo_set_source_rgba(cr, 0, 0, 0, 0);
    cairo_rectangle(cr, x, y, w, h);
    cairo_fill(cr);

    if (binwin)
        cairo_destroy(cr);

    return FALSE;
}

int main(int argc, char *argv[])
{
    GtkWidget *w;
    GtkWidget *q;

    parseargs(argc, argv);
    gtk_init(NULL, NULL);

    w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(w, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    if (!windowonly) {
        if (drawingarea) {
            q = gtk_drawing_area_new();
            if (viewport) {
                GtkWidget *sw;

                sw = gtk_scrolled_window_new(NULL, NULL);
                gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), q);
                q = sw;
            }
        } else {
            q = gtk_layout_new(NULL, NULL);
            if (drawsig)
                g_signal_connect(q, "draw", G_CALLBACK(draw), NULL);
        }
        gtk_container_add(GTK_CONTAINER(w), q);
    }

    gtk_widget_show_all(w);

    gtk_main();
    return 0;
}


推荐答案

添加 GtkCssProvider 到您的窗口中,其中一个或两个

Add a GtkCssProvider to your window with one or both of

GtkLayout {
  background-color: transparent;
}

GtkViewport {
  background-color: transparent;
}

加载。您也可以通过 gtk_widget_override_background_color()执行此操作。

loaded in it. You may also be able to do this with gtk_widget_override_background_color().

这篇关于我如何真正制作GTK + 3 GtkLayout透明/绘制主题背景?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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