2017-01-02 15 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, чтобы реализовать виртуальные методы и попытался портировать код C в Vala. Что может быть причиной проблемы?

+0

Что будет делать ваш виджет? Эта страница gtkmm кажется мне очень странной, особенно с жонглированием GdkWindow, которая, кажется, является удержанием от GTK + 2, но я не совсем уверен? ... – 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/Builder, чтобы точно выяснить, в чем проблема. Я использую следующую команду для отладки Валов/GTK приложений:

    G_DEBUG = фатальных-предупреждения GdB путь/к/исполняемым

  2. Использования встроенных функций GTK, а изобретать его. Если вы хотите сделать виджет определенного размера, используйте Gtk.Widget.set_size_request(), и вам не понадобится 90% кода выше. Чтобы реализовать пользовательский чертеж, создайте Gtk.DrawingArea, подключитесь к сигналу ничьей, выполните это, и все готово.

 Смежные вопросы

  • Нет связанных вопросов^_^