如何在GObject中使用自定义信号?

时间:2015-11-28 12:59:02

标签: python gtk pygobject gobject

我想创建一个带有TreeView小部件的程序及其中的一些项目,这些项目可以通过发出和捕获我称为incr的信号来交换数据。

我创建了10个树项目,将incr信号连接到每个树项目。现在,如果我从其中一个发出incr信号,为什么其他9个人不接收它?

为什么只有发射器对象捕获自身发出的信号?

以下是演示此问题的示例程序:

#!/usr/bin/env python3

from gi.repository import Gtk, GObject


class TreeItem(GObject.GObject):
    __gsignals__ = {
        'incr': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, ())
    }

    def __init__(self, title):
        GObject.GObject.__init__(self)
        self.title = title

    def do_incr(self):
        print('It works!')

GObject.type_register(TreeItem)


class Application(Gtk.Window):
    def __init__(self):
        super().__init__(Gtk.WindowType.TOPLEVEL)
        self.connect('destroy', self.__on_destroy)
        vbox = Gtk.VBox()
        button = Gtk.Button('emit signal')
        button.connect('clicked', self.__on_button_clicked)
        vbox.pack_start(button, False, False, 0)

        list_store = Gtk.ListStore(GObject.GObject)
        text_renderer = Gtk.CellRendererText()
        tree_column = Gtk.TreeViewColumn(None, text_renderer)
        self.__tree_view = Gtk.TreeView(list_store)
        self.__tree_view.append_column(tree_column)
        tree_column.set_cell_data_func(text_renderer, self.__populate_tree)
        vbox.pack_start(self.__tree_view, True, True, 0)
        self.add(vbox)

        self.show_all()

        for i in range(10):
            item = TreeItem(str(i))
            item.connect('incr', self.__on_incr)
            list_store.append((item,))

    def __on_incr(self, item):
        item.title = str(int(item.title) + 1)
        self.__tree_view.queue_draw()

    def __on_button_clicked(self, e):
        selected_item = self.get_selected_item()
        if selected_item:
            selected_item.emit('incr')

    def get_selected_item(self):
        selection = self.__tree_view.get_selection()
        if selection:
            model, iter_ = selection.get_selected()
            return model.get_value(iter_, 0)

    def __populate_tree(self, column, cell, model, iter_, user_data):
        item = model.get_value(iter_, 0)
        cell.set_property('text', item.title)

    def __on_destroy(self, e):
        Gtk.main_quit()


if __name__ == '__main__':
    Application()
    Gtk.main()

2 个答案:

答案 0 :(得分:0)

  

我创建了10个树项目,连接' incr'向他们每个人发出信号,现在如果我发出' incr'其中一个为什么剩下的9个人无法收到它的信号?

当TreeItem发出应用程序收到的信号时,您正在将TreeItems连接到您的应用程序。您的TreeItem与任何东西都没有连接,因此它们什么也得不到。我并不完全确定你想要实现的目标是什么。

答案 1 :(得分:0)

相关部分如下:

    [...]
    for i in range(10):
        item = TreeItem(str(i))
        item.connect('incr', self.__on_incr)
        list_store.append((item,))

您将每个项目连接到一个信号,然后:

def __on_button_clicked(self, e):
    selected_item = self.get_selected_item()
    if selected_item:
        selected_item.emit('incr')

它仅向 selected_item 发出信号,因为这是唯一正在发出的信号。

每个项目连接到同一方法的事实并不意味着当发出信号时,将调用所有项目。每个对象发出的信号,就像你在selected_item.emit('incr')中所做的那样(你知道:对于这个selected_item,请发出信号incr)。其他项目的信号从未发出。