2012-04-25 2 views
2

Я пытаюсь подкласс gtk.DrawingArea. Вот проблема в коде.pyGTK подклассификация выпуск. Двойное самопрохождение к методу

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

Edit: Вопрос заключается в том, чтобы удалить дополнительный аргумент.

ответ

1

Эта задача решается таким образом ..

GTK вызывает функцию обратного вызова следующим образом: cb(widget,event) где виджет экземпляр некоторого класса виджетов. Поэтому мне нужен явный экземпляр referense. Это может быть достигнуто путем выполнения метода из класса 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) 

Первая форма является более гибким.

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)

Таким образом, аргументы, переданные будет виджет и событие. В общей сложности, потому что вы в классе вы будете иметь эти аргументы (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)). И просто используйте def on_mouse_dn(self, event):. Оно не может быть хорошей идеей, хотя (не уверен), в случае, когда изменяется код ...

+0

Да, я понимаю, что args - это 'self',' widget' и 'event'. Но «я виджет», поэтому мне он не нужен (независимо от того, что он называется) дважды. Я могу использовать определение '@ staticmethod' для« исключения »' self'. Но на самом деле это не статический метод, поэтому я считаю, что это неправильное решение. Есть ли другие варианты? – akaRem

+0

Хорошо. Кажется, из вашего вопроса, что вы не знали, откуда взялось «второе» я. Я обновил свой ответ – jadkik94

+0

Спасибо. Извините за неточность в вопросе (английский не мой родной язык). Я думаю, что всплывающие лямбда-обертки не совсем правильны. Особенно, если я определяю много методов. Кажется, есть более элегантное решение. – akaRem

 Смежные вопросы

  • Нет связанных вопросов^_^