我正在构建一个包含多个小部件的PyGTK应用程序,在更改后,需要通知其他小部件有关更改。我想避免这样的代码:
def on_entry_color_updated(self, widget):
self.paint_tools_panel.current_color_pane.update_color()
self.main_window.status_bar.update_color()
self.current_tool.get_brush().update_color()
做一些这样的事情:
def on_entry_color_updated(self, widget):
self.update_notify('color-changed')
状态栏,当前颜色窗格和当前工具将订阅该通知事件并采取相应措施。据我所知,GObject信令机制只允许我在特定小部件上注册回调,因此每个想要接收通知的对象都必须知道该小部件。
GTK是否提供这样的系统,还是应该自己构建?如果我了解他们的{{3},那么GNOME照片组织应用程序Shotwell的开发人员必须建立自己的信令机制。正确的。在这里搜索SO并没有找到任何确定的答案。
澄清为什么我认为GObject信号不是我需要的(或者只是我需要的一部分)。使用GObject,我需要将对象显式连接到另一个对象,如下所示:
emitter.connect('custom-event', receiver.event_handler)
所以在我的申请中,我必须这样做:
class ColorPane(gtk.Something):
def __init__(self, application):
# init stuff goes here...
application.color_pallette.connect('color-changed', self.update_color)
def update_color(self, widget):
"""Show the new color."""
pass
class StatusBar(gtk.Something):
def __init__(self, application):
# init stuff goes here...
application.color_pallette.connect('color-changed', self.update_color)
def update_color(self, widget):
"""Show the new color name."""
pass
class Brush(gtk.Something):
def __init__(self, application):
# init stuff goes here...
application.color_pallette.connect('color-changed', self.update_color)
def update_color(self, widget):
"""Draw with new color."""
pass
换句话说,我必须将应用程序对象或其他知道color_pallete的对象传递给我的应用程序中的其他对象,以便它们连接到color_pallette信号。这是我想要避免的那种耦合。
答案 0 :(得分:1)
首先,您可以创建GObject
的自定义子类,其中提供了一些custom signals。以下示例是链接文章中给出的稍微改编的版本:
import pygtk
pygtk.require('2.0')
import gobject
class Car(gobject.GObject):
__gsignals__ = {
'engine-started': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
'engine-stopped': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
}
def __init__(self):
gobject.GObject.__init__(self)
self._state = 0
def start(self):
if not self._state:
self._state = 1
self.emit('engine-started')
def stop(self):
if self._state:
self._state = 0
self.emit('engine-stopped')
gobject.type_register(Car)
def kill_switch(c):
def callback(*unused, **ignored):
c.stop()
return callback
def on_start(*unused, **ignored):
print "Started..."
def on_stop(*unused, **ignored):
print "Stopped..."
some_car = Car()
some_car.connect('engine-started', on_start)
some_car.connect('engine-started', kill_switch(some_car))
some_car.connect('engine-stopped', on_stop)
some_car.start()
另一种方法是利用PyPI上已有的众多事件/信令包之一,例如:
答案 1 :(得分:1)
GObjects不一定是小部件。例如,您的应用程序类可以是GObject,它定义其他小部件连接的信号。
另外,我认为您没有正确理解Shotwell设计文档。在我看来,他们的信号系统是100%GObject信号系统,只是特别保证信号的处理顺序。正如他们在设计文档中所说的那样,在简单的GObject中这样的事情是可能的,但Vala使得用它们编写代码变得更容易。