pyGTK子类化问题。双重自我传递给方法

时间:2012-04-25 18:46:09

标签: python pygtk subclassing

我正在尝试子类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)>

编辑:问题是如何删除额外的参数。

2 个答案:

答案 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)

第一种形式更灵活。