编辑帖子末尾的新信息。
长话短说,我需要为大多数gtk widget系列添加多个方法和属性。许多相同,许多小部件具体。最终结果是我需要子类gtk.Widget,gtk.Object和几个特定的小部件(例如,Entry,Label,TextView)。
我的问题是这个。当我在MyObject,MyWidget和MyWindow中创建新属性时,我编写代码来测试MyObject,并且存在属性(和信号)。
然后MyWidget继承自MyObject和gtk.Widget。所有属性和信号都存在并占据。
MyWindow然后继承自MyWidget和gtk.Window。来自MyObject的所有属性和信号都消失了。
使用在类定义中创建对象和信号
__gsignals__ = {<much data goes here>}
__gproperties__ = {<lots goes here>}
在定义类之后,从可导入文件的主体级别调用gobject.type_register(MyClass)
。
写了几个测试变体,调用了init(特别是inits(gtk.Widget.__init__(self)
)和self.gobject_init()
的super()版本,甚至尝试了gtk.Widget.__gobject_init__(self)
所有这些似乎都失去了属性和信号的祖父母级别(或更糟)。
我得出的结论是,我没有正确理解如何使用子类小部件实例化gtk类。关于子类别gobject(http://www.pygtk.org/articles/subclassing-gobject/sub-classing-gobject-in-python.htm)的文章过去是我的主要指南,虽然它提到了这个问题,但解释是模糊地帮助我(或者我要密集得到它)。 / p>
有人会非常友好地指出我,或者展示一个有效的信号/属性的祖父母级别继承的例子吗?我找不到任何谷歌。
同样有用的可能是__gobject_init_
做什么(如何做)的解释。如果需要,我可以编写自定义版本,但我找不到任何文档。
(我是从教堂写的,我没有任何实际的代码可以发帖,抱歉。)
更新一次:
好的示例代码说明了问题,我现在意识到这比我原先想象的要糟糕。即使在父级别,继承也会丢失。
附加两个代码示例区域,两者都相同。第一个是人类可读(pep8),可以复制粘贴到文档中并执行。它运行但在窗口被破坏后提供说明性输出,解释问题并证明它们存在。
第二个是不太可读,但是直接复制粘贴到python解释器中的代码是相同的。
第一个代码集: 此代码的输出表明没有信号或属性的继承发生。
import gtk, gobject, pygtk
pygtk.require("2.0")
class DummyClass(gtk.Object):
def __init__(self):
self.dummycode = None
gtk.Object.__init__(self)
class TObject(gtk.Object):
__gproperties__ = {
"testproperty":
(
gobject.TYPE_STRING,
"nick",
"blurb",
"value of test string",
gobject.PARAM_READABLE
)
}
__gsignals__ = {}
def do_get_property(self, prop):
if prop.name == "testproperty":
return self.testproperty
def do_set_property(self, prop):
pass
def __init__(self):
self.testproperty = ""
gtk.Object.__init__(self)
gobject.type_register(TObject)
class TWidget(gtk.Widget, TObject, DummyClass):
__gproperties__ = {
"testproperty2":
(
gobject.TYPE_STRING,
"nick",
"blurb",
"value of test string2",
gobject.PARAM_READABLE
)
}
__gsignals__ = {}
def do_get_property(self, prop):
if prop.name == "testproperty2":
return self.testproperty2
def do_set_property(self, prop):
pass
def __init__(self):
self.testproperty2 = "But it's right here."
# TObject.__gobject_init__(self)
# gtk.Widget.__gobject_init__(self)
self.__gobject_init__()
self.add_events(
gtk.gdk.BUTTON_PRESS_MASK |
gtk.gdk.BUTTON_RELEASE_MASK
)
TObject.__init__(self)
DummyClass.__init__(self)
gobject.type_register(TWidget)
class TWindow(gtk.Window, TWidget):
__gproperties__ = {
"testproperty3":
(
gobject.TYPE_STRING,
"nick",
"blurb",
"value of test string3",
gobject.PARAM_READABLE
)
}
__gsignals__ = {}
def do_get_property(self, prop):
if prop.name == "testproperty3":
return self.testproperty3
def do_set_property(self, prop):
pass
def __init__(self, type=gtk.WINDOW_TOPLEVEL, dummyarg=""):
self.testproperty3 = dummyarg
TWidget.__init__(self)
gtk.Window.__init__(self)
gobject.type_register(TWindow)
if __name__ == "__main__":
def on_destroy(*args, **kwargs):
try:
print "Trying to get testproperty2"
print args[0].get_property("testproperty2")
except TypeError:
print "\tNo such property."
print "Getting it from the associated variable..."
print "\t", args[0].testproperty2
print "Recognized properties are..."
ct = 0
base = "{:<20}{}\n\t"
out = "\t"
for x in args[0].props:
ct += 1
if ct % 2 == 0:
out += base.format(x1, x.name)
x1 = None
continue
else:
x1 = x.name
if x1 is None:
print out
else:
print out, x1
print (
"NOTE: testproperty and testproperty2 do not appear in the list.\n"
" (Defined in TObject and TWidget respectively.)")
gtk.mainquit()
win = TWindow()
l = gtk.Label("Just close me\nand watch the output.")
win.add(l)
win.connect("destroy", on_destroy)
win.show_all()
gtk.main()
第二个代码集: 好的,这个愚蠢的形式不会让我把它放进去.SO代码只设置一个。