【问题标题】:Why GtkWindow does not fire "draw" event?为什么 GtkWindow 不触发“绘制”事件?
【发布时间】:2012-05-21 22:01:45
【问题描述】:

我正在尝试使用 GTK+ 3.x 获得一个透明窗口。 AFAIK 下面的代码应该可以工作,但我的窗口永远不会触发“draw”信号。可能是什么原因?

我的代码:

using Gtk;

public class WallpaperWindow : Object {
  private Window  window;

  public static int main (string[] args) {
    Gtk.init (ref args);

    new WallpaperWindow();

    Gtk.main();

    return 0;
  }

  public WallpaperWindow() {
    // Initialize window
    this.window = new Window();
    this.window.resize(200, 200);

    this.window.set_decorated(false);
    this.window.set_border_width(8);


    // Enable transparency

    var screen = this.window.get_screen();
    var visual = screen.get_rgba_visual();

    if(visual != null && screen.is_composited()) {
      message("Composition is enabled, enabling transparency");
      this.window.set_visual(visual);
    } else {
      warning("Composition is not enabled, cannot enable transparency");
    }

    this.window.draw.connect(on_window_draw);

    // Run!
    this.window.show_all();

  }

  // NEVER CALLED
  private bool on_window_draw(Cairo.Context cr) {
    warning("on_window_draw");
    cr.set_source_rgba(0.0, 0.0, 0.0, 0.0);
    cr.set_operator(Cairo.Operator.SOURCE);
    cr.paint();
    cr.set_operator(Cairo.Operator.OVER);

    return true;
  }
}

【问题讨论】:

    标签: gtk vala


    【解决方案1】:

    您没有将新创建的 WallpaperWindow 实例分配给变量。 Vala 不是垃圾收集...当一个对象超出范围时,它立即取消引用,如果你不将它分配给一个变量,它会在构造函数的末尾超出范围称呼。从您的示例中生成的 C 如下所示:

    _tmp0_ = wallpaper_window_new ();
    _tmp1_ = _tmp0_;
    _g_object_unref0 (_tmp1_);
    gtk_main ();
    

    如您所见,在调用 gtk_main 之前,您的新 WallpaperWindow 会被取消引用。如果你将它分配给一个变量(所以它持续超过gtk_main)你的例子就像你期望的那样工作。

    【讨论】:

      【解决方案2】:

      C 中的转置按预期工作。

      #include <gtk/gtk.h>
      
      static gboolean
      on_window_draw(GtkWidget *window, cairo_t *cr)
      {
          g_message("Called!\n");
      
          cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
          cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
          cairo_paint(cr);
          cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
      
          return TRUE;
      }
      
      int main(int argc, char *argv[])
      {
          GtkWidget *window;
          GdkScreen *screen;
          GdkVisual *visual;
      
          gtk_init(&argc, &argv);
      
          window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
          gtk_window_resize(GTK_WINDOW(window), 200, 200);
      
          gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
      
          screen = gtk_window_get_screen(GTK_WINDOW(window));
          visual = gdk_screen_get_rgba_visual(screen);
      
          if (visual != NULL && gdk_screen_is_composited(screen)) {
              g_message("Composition is enabled, enabling transparency");
              gtk_widget_set_visual(window, visual);
          } else {
              g_message("Composition is not enabled, cannot enable transparency");
          }
      
          g_signal_connect(window, "draw", G_CALLBACK(on_window_draw), NULL);
      
          gtk_widget_show_all(GTK_WIDGET(window));
      
          gtk_main();
          return 0;
      }
      

      这就是我得到的:

      $ gcc $(pkg-config --cflags --libs gtk+-3.0) a.c
      $ ./a.out
      ** Message: Composition is enabled, enabling transparency
      ** Message: Called!
      
      ** Message: Called!
      
      ** Message: Called!
      
      ** Message: Called!
      

      【讨论】:

        猜你喜欢
        • 2021-07-16
        • 2011-12-03
        • 2014-12-06
        • 1970-01-01
        • 1970-01-01
        • 2014-05-28
        • 2011-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多