我正在尝试子类gtk.DrawingArea。 这是代码中的问题部分。
class ClusterGraph(gtk.DrawingArea):
def __init__(self):
super(ClusterGraph, self).__init__()
self.add_events(gtk.gdk.BUTTON_PRESS_MASK)
self.connect('button-press-event', self.on_mouse_dn)
def on_mouse_dn(*args):
print args
window = gtk.Window()
window.connect("destroy", gtk.main_quit)
window.set_default_size(300, 600)
cg = ClusterGraph()
window.add(cg)
window.show_all()
gtk.main()
问题是该实例被传递给该方法两次。
单击打印:
(<ClusterGraph object at 0x30167d8 (GtkDrawingArea at 0x2531610)>, <ClusterGraph object at 0x30167d8 (GtkDrawingArea at 0x2531610)>, <gtk.gdk.Event at 02F75F08: GDK_BUTTON_PRESS x=164,00, y=354,00, button=1>)
我的回调实际上等同于
def on_mouse_dn(self, self, event)
如何解决这个问题?或者这是正常的!?
顺便说一句,为什么打印<ClusterGraph object at 0x30167d8 (GtkDrawingArea at 0x2531610)>
而不是
<ClusterGraph object at 0x30167d8 (ClusterGraph at 0x2531610)>
编辑:问题是如何删除额外的参数。
答案 0 :(得分:1)
在定义方法时,不包含self,因此在调用时,args将包含self和其他参数。
因为它是pygtk事件处理程序,所以它的定义应该如下:
57 def button_press_event(widget, event):
58 if event.button == 1 and pixmap != None:
59 draw_brush(widget, event.x, event.y)
60 return True
(来自pygtk tutorial)
因此,传递的参数将是widget和event。总的来说,因为你在课堂上,你会有这些论据(self, widget, event)
由于您正在执行self.connect
,这意味着widget
将评估为self
。所以,你得到的论点是(self, self, event)
。
使用def on_mouse_dn(self, widget, event):
或def on_mouse_dn(self, *args):
。第一个似乎最有意义......
UPDATE :要不将widget
作为参数传递,您必须使用像self.connect('button-press-event', lambda w, e: self.on_mouse_dn(e))
这样的lambda。然后使用def on_mouse_dn(self, event):
。虽然(不确定)可能不是一个好主意,以防你的代码发生变化......
答案 1 :(得分:1)
这个问题以这种方式解决了。
GTK以这种方式调用回调:cb(widget,event)
其中widget是某个widget类的实例。所以我需要明确的实例参考。这可以通过从类obj执行方法来实现。
self.connect('button-press-event', self.on_mouse_dn)
应替换为
self.connect('button-press-event', self.__class__.on_mouse_dn)
或
self.connect('button-press-event', ClusterGraph.on_mouse_dn)
第一种形式更灵活。