2013-03-11 79 views
1

所以你有一些功能,比如Gtk.Builder.get_object(),它返回一些小部件。在我們的案例中,一個Gtk.Window()從超類實例構造類

我有一個Gtk.Window()的子類,它增加了一些信號處理程序。

class Window(Gtk.Window): 

是否有可能使用由Gtk.Builder.get_object()返回的小部件來構建Window()?我認爲它應該使用__new__()什麼的,但我無法弄清楚。

+0

您可以寫入您正在獲取的'Gtk.Window'實例的'__class__'屬性嗎? – Blckknght 2013-03-11 03:58:49

+0

@Blckknght安全嗎?我在'__new __()'中設置了'window .__ class__ = cls'的快速測試。我似乎能夠從這個子類調用方法,但是'__init__'仍然沒有運行。根據我對文檔的理解,它應該如此,所以IDK。 – ABP 2013-03-11 04:26:34

+0

只要您設置的類是實例上一個類的子類,它就應該是安全的。我不確定爲什麼如果你從'__new__'返回修改後的實例,它不會調用'__init__'。我會把這個建議寫成答案,但在我們弄清楚發生了什麼問題之前,請隨時不要接受它。 – Blckknght 2013-03-11 04:53:24

回答

1

我認爲使用__new__正是你想要做的。如果您可以設置您獲得子類的超類實例的__class__屬性,則應該全部設置。

這就是我想你需要:

class Window(Gtk.Window): 
    def __new__(cls, *args, **kwargs): 
     self = Gtk.Builder.get_object() 
     self.__class__ = cls 
     return self 

Python的應該檢測,是由__new__創造的價值是類的一個實例(感謝__class__值),則它會調用__init__等適當的方法。

+0

@ABP - 這應該起作用。在CPython中,可以安全地爲具有兼容內存佈局的堆類型實例重新分配'__class__',該內存佈局在運行時檢查。如果'__init__'沒有運行,則元類'__call__'方法必須被覆蓋。 – eryksun 2013-03-11 05:12:42

+0

好吧,這似乎確實工作,實際上。我定義了新的像'def __ new __(cls,data_dir)'並創建了像Window.__ new __(Window,'..')這樣的對象,但是這必須是不正確的。 – ABP 2013-03-11 05:44:13

+0

我剛剛檢查過,'gobject.GObjectMeta'不會覆蓋'type .__ call__'。 – eryksun 2013-03-11 05:44:40