2013-04-07 78 views
1

我想在Vala中創建一個自定義的GTK小部件,但是在第一次基本嘗試時我已經失敗了,所以我想要知道我要去哪裏的一些幫助錯誤。我覺得我一定會錯過顯而易見的東西,但我看不到它。Vala中的自定義GTK小部件無法正常工作

我有三個文件包含以下內容:

start.vala

using Gtk; 

namespace WTF 
{ 
     MainWindow main_window; 

     int main(string[] args) 
     { 
       Gtk.init(ref args); 
       main_window = new MainWindow(); 
       Gtk.main(); 
       return 0; 
     } 
} 

main_window.vala

using Gtk; 

namespace WTF 
{ 
     public class MainWindow : Window 
     { 
       public MainWindow() 
       { 
         /* */ 
         Entry entry = new Entry(); 
         entry.set_text("Yo!"); 
         this.add(entry); 
         /* */ 

         /* 
         CustomWidget cw = new CustomWidget(); 
         this.add(cw); 
         /* */ 

         this.window_position = WindowPosition.CENTER; 
         this.set_default_size(400, 200); 
         this.destroy.connect(Gtk.main_quit); 

         this.show_all(); 
       } 
     } 
} 

custom_widget.vala

using Gtk; 

namespace WTF 
{ 
     public class CustomWidget : Bin 
     { 
       public CustomWidget() 
       { 
         Entry entry = new Entry(); 
         entry.set_text("Yo"); 
         this.add(entry); 
         this.show_all(); 
       } 
     } 
} 

正如你所看到的,在main_window.vala中,我有兩組代碼。一個直接添加Entry小部件,另一個添加我的自定義小部件。如果你運行一個與自定義窗口小部件

functioning widget

,但是,你會得到這樣的結果:如果您運行的一個直接加到輸入構件,你會得到這樣的結果

malfunctioning widget

只是爲了記錄在案,這是複雜的命令我使用:

valac --pkg gtk+-2.0 start.vala main_window.vala custom_widget.vala -o wtf 

編輯:

繼user4815162342的建議下,我實現了size_allocate方法上我的自定義斌部件,像這樣:

public override void size_allocate(Gdk.Rectangle r) 
{ 
     stdout.printf("Size_allocate: %d,%d ; %d,%d\n", r.x, r.y, r.width, r.height); 
     Allocation a = Allocation() { x = r.x, y = r.y, width = r.width, height = r.height }; 
     this.set_allocation(a); 

     stdout.printf("\tHas child: %s\n", this.child != null ? "true" : "false"); 
     if (this.child != null) 
     { 
       int border_width = (int)this.border_width; 
       Gdk.Rectangle cr = Gdk.Rectangle() 
       { 
         x = r.x + border_width, 
         y = r.y + border_width, 
         width = r.width - 2 * border_width, 
         height = r.height - 2 * border_width 
       }; 
       stdout.printf("\tChild size allocate: %d,%d ; %d, %d\n", cr.x, cr.y, cr.width, cr.height); 
       this.child.size_allocate(cr); 
     } 
} 

它寫在控制檯如下:

Size_allocate: 0,0 ; 400,200 
     Has child: true 
     Child size allocate: 0,0 ; 400, 200 

而窗口如此渲染:

partially functioning widget

回答

2

GtkBin是一個抽象的獨子容器,通常旨在以某種方式修飾子部件,或者更改其可見性或大小。沒有一些附加價值,獨立子容器與它所包含的小部件不可區分,因此不是很有用。

由於GtkBin不知道你會在孩子身上畫什麼樣的裝飾品,它期望你實現你自己的size_allocategtk_event_area_size_allocate中有一個簡單的實現,gtk_button_size_allocate中更復雜。

This answer在PyGTK中顯示了一個最簡單的size_allocate實現,該實現應該可以直接移植到Vala。如果你做了比這更復雜的任何事情,你還需要執行expose以及其他可能的方法,但這會讓你開始。

+0

謝謝,我完全沒有意識到GtkBin小部件對於自己的通用容器是無用的。根據你所說的話,我決定從GtkEventBox繼承,而那裏的一切似乎都很出色。我試着從你的Vala鏈接中實現最小的size_allocate,但是結果並不好,嘿。 – Alex 2013-04-07 10:43:12

+2

@Alex你不能實例化它有點讓步。 :)'GtkEventBox'提供了一個更溫和的介紹,但它確實帶有一些你不需要的附加功能。它還強制容器的GDK窗口,如果不需要,這是浪費。一旦你更熟悉小部件的低級工作,你可能想回到'GtkBin'。 – user4815162342 2013-04-07 11:28:29

+0

是的,我稍後可能會嘗試一下......沒有設法實現size_allocate,這是令人失望的。我99%肯定我做了Python版本,但是當我的版本渲染時,我看到的所有渲染都是細線,而不是輸入文本框。 – Alex 2013-04-08 09:04:35

相關問題