2012-03-09 51 views
1

要開始,我是perl或使用gtk沒有經驗的腳本,但我一直在搜索和研究如何在過去的兩個星期左右。我很難搞清楚我在哪裏可以在windows上找到用於gtk的PM,然後更加容易找到某種「工作」的外表。但是,當然仍然存在問題。在Perl中使用gtk構建器的多個窗口實例

跳過上述,我有兩個問題。對於一些相關的背景,我試圖將一個mirc腳本移植到xchat,但是爲了做到這一點,我顯然需要學習整個'其他語言......但無論如何。這兩個問題是這樣的:

  1. 窗口由幾個按鈕,標籤和文本區域組成。但是,除非點擊標題欄並持有,否則該窗口會被及時「凍結」。點擊一個按鈕什麼都不做,甚至不顯示它被點擊,除非標題欄被點擊並保持。

  2. 我不知道如何初始化同一窗口的多個實例。我當然試過研究,但是要麼沒有在那裏,要麼我還沒有找到它。具體而言..我的mirc腳本要求允許多個實例存在,但我需要特定實例的按鈕纔會影響該實例..等等。

關於問題1,我不知道.xml glade文件是否重要,所以我不會立即發佈它。然而,我會發布代碼來調用它:

my $glade_file = "window3.xml"; 
my $glade = Gtk2::Builder->new(); 
$glade->add_from_file($glade_file); 

sub charopen { 
    my $window = $glade->get_object('window1'); 
    $glade->connect_signals(undef, $window); 
    my $hp_cur = $glade->get_object('HP_Cur'); 
    $window->set("title"=>$_[0][1]); 
    $hp_cur->set("label"=>$ini->val($_[0][1],"HPC")); 
    $window->show(); 
} 
+0

給[足夠的信息](http://sscce.org/),以便我們[重現問題](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html#showmehow )。 – daxim 2012-03-09 09:08:28

+1

你正在調用'Gtk2-> main();'某處,對嗎? – charlesbridge 2012-03-09 12:34:52

+0

我沒有。這解決了問題1,但問題2仍然存在。謝謝。 – Daedalus 2012-03-09 20:17:46

回答

0

圖形界面設計依賴於事件處理。爲了正常工作,保留一個線程來處理用戶事件(鍵盤,鼠標點擊...)非常重要。這是當用戶界面準備好接受用戶交互時調用Gtk2->main()的目的。

爲了使事件線程退出事件循環,事件回調方法可以調用Gtk2->main_quit()

Gtk2::Builder從XML創建基於GTK控件層次結構。要獲得同一窗口的多個實例,您必須爲每個實例創建一個構建器。

然後,您的事件回調方法必須獲取有關哪個窗口發送了事件的信息,並且可以在該目標中使用參數$user_data

下面是與使用Perl引用的哈希一個簡單的按鈕點擊回調代碼的建議,所以你可以,只要你想窗口創建者代碼和事件回調之間傳遞儘可能多的信息:

sub createWindow($) 
    my $windowTitle = $_[0]; 
    my $windowBuilder = Gtk2::Builder->new(); 
    $windowBuilder->add_from_file($glade_file); 
    my $window = $windowBuilder->get_object('window1'); 
    my $hp_cur = $windowBuilder->get_object('HP_Cur'); 

    # Create hash with data (alternative: use Class::Struct for better code) 
    my %window_user_data = { 
     "title" => $windowTitle, 
     "window" => $window, 
     "hp_cur" => $hp_cur }; 
    # Pass hash reference as user data 
    $windowBuilder->connect_signals(\%window_user_data); 

    # prepare interface: set data model into view and then... 
    $window->show(); 
} 

# Click callback method defined on a button in window 
sub button_click_callback($$) { 
    my $button = $_[0]; 
    my $window_user_data_ref = $_[1]; 
    # get back data model from view 
    print "Click received from button on " 
     . $window_user_data_ref->{"title"} . "\n"; 
} 

還有另一種方法來處理每個窗口的回調,但它需要更多的Perl技能:你可以設計一個Perl包來爲特定的窗口創建一個對象實例,並使用$windowbuilder->connect_signals ($user_data, $windowcallbackinstance)。在這種情況下,這樣的對象稱爲控制器,並且您已經基於Model-View-Controller (MVC) pattern構建了圖形界面。