2016-03-01 28 views
1

對於我正在處理的項目,我使用的是自定義信號,這些自定義信號發送給子級,然後在信號未完全處理時傳播給它父級。自定義信號不傳播

根據我可以發現的信息,似乎在回調中沒有連接處理程序(使用connect)或返回False應允許信號傳播到小部件父項。

然而,在低於這個我的玩具例如不工作:

class MyWindow(Gtk.Window): 
    def __init__(self): 
     Gtk.Window.__init__(self) 

     GObject.signal_new("print-this", GObject.TYPE_OBJECT, GObject.SIGNAL_RUN_LAST, GObject.TYPE_BOOLEAN, [GObject.TYPE_STRING]) 

     self.button = Gtk.Button.new_with_label("Emit signals") 
     self.button.connect("clicked", self.emit_signals) 

     self.frame = Gtk.Frame.new("Some frame") 
     self.frame.add(self.button) 
     self.add(self.frame) 

     self.connect("print-this", self.got_it) 
     self.show_all() 
     Gtk.main() 

    def got_it(self, widget, string): 
     print string 
     return False 

    def emit_signals(self, *args): 
     print "Emitting signals.." 
     self.button.emit("print-this", "I was emitted from the button") 
     time.sleep(1) 
     self.frame.emit("print-this", "I was emitted from the frame") 
     time.sleep(1) 
     self.emit("print-this", "I was emitted from the window") 

當信號發出我期望打印所有三個發射但我只得到窗口上的發出打印。這可能是由於信號根本沒有傳播。

那麼我在哪裏錯了?更重要的是,我如何才能實現我正在尋找的傳播行爲?

+0

信號與GObject類相關聯。 'print-this'信號只存在於你的'MyWindow'類中,而不是'GtkButton'或'GtkFrame',所以'self.button.emit()'和'self.frame.emit()'調用不存在信號。反正你什麼也得不到;即使這些信號確實存在,也沒有任何東西與他們連接。 – andlabs

+0

我認爲'GObject.signal_new'會將信號與所有GObject類關聯,但根據您的評論,我認爲這是錯誤的?那麼我需要如何定義它們呢? (當然下一步將是他們如何傳播?) – B8vrede

+0

你認爲信號如何工作? (我不知道Python,但我假設'GObject.'正在調用GObject類的'signal_new()'實例方法'self')。知道這可以幫助我清除你的誤解。 – andlabs

回答

2

通用GObject信號不會通過GTK小部件樹傳播。只有事件相關的信號才能做到這一點,並且它在內部完成inside GTK

如果您希望遞歸發射信號,您必須添加一個函數,該函數在樹中的每個小部件上調用g_signal_emit()

+0

哦,實際上是有道理的,所以對於傳播是上面的例子,按鈕和幀都應該通過連接到每個信號中來傳遞信號,然後使用'g_signal_emit'發送給它的父節點? – B8vrede

+1

這很奇怪,請記住:信號是同步的。如果您開始在信號內部發射信號,則可能會出現可擴展性災難。我寧願寫我寫的內容,並添加一個信號發射器函數,在內部進行層次遍歷。另外,如果您向某個類添加信號並且想要將其發送到它的小部件的父級,則還需要將其添加到父級的類中。 – ebassi