2017-01-02 20 views
2

我试图创建一个使用瓦拉一个简单的自定义窗口小部件GTK:定制GTK控件与瓦拉

public class PageView : Gtk.Widget { 

    public PageView() { 
     //base(); 
     set_name ("pageview"); 
     set_has_window (true); 
    } 


    /* 
    *    Method and Signal Overrides 
    */ 

    public override Gtk.SizeRequestMode get_request_mode() { 
     return Gtk.SizeRequestMode.CONSTANT_SIZE; 
      // Don’t trade height-for-width or width-for-height 
    } 

    public override void get_preferred_width 
               (out int minimum, 
               out int natural) { 
     stdout.printf ("PageView#get_preferred_width\n"); 
     minimum = natural = pg_pixel_width; 
    } 

    public override void get_preferred_height 
               (out int minimum, 
               out int natural) { 
     stdout.printf ("PageView#get_preferred_height\n"); 
     minimum = natural = pg_pixel_height; 
    } 

    public override void get_preferred_width_for_height 
               ( int height, 
               out int minimum, 
               out int natural) { 
     stdout.printf ("PageView#get_preferred_width_for_height\n"); 
     minimum = natural = pg_pixel_width; 
    } 

    public override void get_preferred_height_for_width 
               ( int width, 
               out int minimum, 
               out int natural) { 
     stdout.printf ("PageView#get_preferred_height_for_width\n"); 
     minimum = natural = pg_pixel_height; 
    } 


    public override void size_allocate (Gtk.Allocation alloc) { 
     stdout.printf ("PageView#size_allocate\n"); 

     set_allocation (alloc); 

     if (get_window() != null) { 
      get_window().move_resize (
       alloc.x, alloc.y, alloc.width, alloc.height); 
     } 
    } 

    public override void realize() { 
     stdout.printf ("PageView#realize\n"); 

     set_realized (true); 

     if (get_window() == null) { 
      Gtk.Allocation allocation; 
      get_allocation (out allocation); 
      _window_attr = Gdk.WindowAttr() { 
       x = allocation.x, 
       y = allocation.y, 
       width = allocation.width, 
       height = allocation.height, 
       event_mask = get_events() | Gdk.EventMask.EXPOSURE_MASK, 
       window_type = Gdk.WindowType.CHILD, 
       wclass = Gdk.WindowWindowClass.INPUT_OUTPUT 
      }; 
      _window_attr_type = Gdk.WindowAttributesType.X | 
           Gdk.WindowAttributesType.Y; 

      _window = new Gdk.Window (
       get_parent_window(), _window_attr, _window_attr_type); 
      set_window (_window); 
     } 
    } 

    public override void unrealize() { 
     stdout.printf ("PageView#unrealize\n"); 
    } 


    public override bool draw (Cairo.Context cr) { 
     stdout.printf ("PageView#draw\n"); 

     Gtk.Allocation allocation; 
     get_allocation (out allocation); 
     get_style_context() .render_background (cr, 
      allocation.x,  allocation.y, 
      allocation.width, allocation.height); 

     cr.save(); 
      cr.scale (allocation.width, allocation.height); 
      cr.set_source_rgba (255, 255, 0, 1.0); 
      cr.set_line_width (10); 
      cr.line_to (1, 1); 
      cr.stroke(); 
     cr.restore(); 


     return true; 
    } 


    /* 
    *     Public Attributes 
    */ 

    public int pg_pixel_width { 
     get { return 480; } 
    } 

    public int pg_pixel_height { 
     get { return 480; } 
    } 


    /* 
    *     Private Members 
    */ 

    private Gdk.Window  _window; 

    private Gdk.WindowAttr _window_attr; 

    private Gdk.WindowAttributesType _window_attr_type; 

} 

的问题是,当我加入这个我的主要Gtk.Window我得到一个分段错误。这些都是调试消息我得到:

PageView#get_preferred_height 
PageView#get_preferred_width 
PageView#size_allocate 
PageView#realize 
PageView#get_preferred_height 
PageView#get_preferred_width 
PageView#size_allocate 
PageView#size_allocate 
Segmentation fault (core dumped) 

看来,如果我改变的set_window (_window)realize()调用set_window(null),或者如果我传递一个空的父窗口到新创建的Gdk.Window,应用程序运行时不分段错误(但是无论在哪种情况下都不会显示小部件)。我主要沿着this example来实现虚拟方法,并尝试在Vala中移植C代码。什么可能是问题的原因?

+0

您的小部件要做什么?那gtkmm页面对我来说似乎很奇怪,尤其是对于似乎从GTK + 2延续下来的GdkWindow杂耍,但我不太确定?... – andlabs

+0

基本上,我尝试了一下,试图从Gtk.TextBuffer就可以了,但还没有想出如何正确渲染! –

回答

1

最后,我从构造除去set_has_window(true)和仅实施了draw()信号。这似乎已经成功了!以下是工作代码段:

public class PageView : Gtk.Widget { 

    public PageView() { 
     set_name ("pageview"); 
    } 


    /* 
    *    Method and Signal Overrides 
    */ 

    public override Gtk.SizeRequestMode get_request_mode() { 
     return Gtk.SizeRequestMode.CONSTANT_SIZE; 
      // Don’t trade height-for-width or width-for-height 
    } 

    public override void get_preferred_width 
               (out int minimum, 
               out int natural) { 
     stdout.printf ("PageView#get_preferred_width\n"); 
     minimum = natural = pg_pixel_width; 
    } 

    public override void get_preferred_height 
               (out int minimum, 
               out int natural) { 
     stdout.printf ("PageView#get_preferred_height\n"); 
     minimum = natural = pg_pixel_height; 
    } 

    public override void size_allocate (Gtk.Allocation alloc) { 
     stdout.printf ("PageView#size_allocate\n"); 
     base.size_allocate (alloc); 

    } 

    public override void realize() { 
     stdout.printf ("PageView#realize\n"); 
     base.realize(); 
    } 

    public override void unrealize() { 
     stdout.printf ("PageView#unrealize\n"); 
     base.unrealize(); 
    } 


    public override bool draw (Cairo.Context cr) { 
     stdout.printf ("PageView#draw\n"); 

     Gtk.Allocation allocation; 
     get_allocation (out allocation); 

     cr.set_line_width (1); 
     cr.set_source_rgba (255, 255, 0, 1);  
     cr.save(); 
      cr.scale (allocation.width, allocation.height); 
      cr.move_to (0, 0); 
      cr.line_to (1, 1); 
     cr.restore(); 
     cr.stroke(); 

     return false; 
    } 

    ... 

} 
0

一对夫妇的建议在这里:

  1. 调试使用GDB/Nemvier /生成器来找出到底是什么问题了崩溃的应用程序。我用下面的命令行调试VALA/GTK程序:

    G_DEBUG =致命的警告GDB路径/到/可执行

  2. 使用内置的GTK功能,而重塑它。如果你想使一个特定的尺寸,使用Gtk.Widget.set_size_request(),你不需要90%的上述代码。要实现自定义绘图,请创建一个Gtk.DrawingArea,连接到绘图信号,执行该绘图,然后完成。