如何处理" notify :: active"来自Gtk.Switch的信号? (MVC架构)

时间:2018-05-09 17:21:12

标签: python gtk gtk3 pygobject

我无法弄清楚如何处理notify::active的{​​{1}}信号。我正在使用MVC架构(模式)suggested here

我得到的错误是:

Gtk.Switch

这是我最小的工作示例(没有模型):

TypeError: _on_switch_serial_toggled() missing 1 required positional argument: 'state'

1 个答案:

答案 0 :(得分:0)

首先,您正在正确处理notify 几乎active属性的Gtk.Switch信号。问题在于处理您已添加到View中的自定义信号。

理解你在做什么很重要:你创建了一个具有属性的View类,它是一个Gtk.Switch。您还创建了一个与此类关联的名为switch_serial_toggled的信号。在类中,你想要的是,当内部Gtk.Switch改变状态时,View会触发它自己的“切换”信号。

这就是说,让我们修复你的代码:

1 - 让我们将切换状态作为布尔值添加到视图switch_serial_toggled

class View(Gtk.ApplicationWindow):
    __gsignals__ = {
        'switch_serial_toggled': (GObject.SIGNAL_RUN_FIRST, None, (bool,))
    }

2 - 让我们给View内部信号处理程序的参数赋予适当的名称,并将状态添加到发出的信号中:

def on_switch_serial_toggled(self, obj, pspec):
    self.emit('switch_serial_toggled', self._switch_serial.get_active ())

GObject.Object通知信号处理程序是described here

3 - 现在,让我们转到Controller并正确处理View信号:

def _on_switch_serial_toggled(self, widget, active):
        if active is True:
            print('Switch ON')
        else:
            print('Switch OFF')

widget参数是Controller实例中的View实例,state是通过信号发射传递的布尔值。

完整代码以及上面的修补程序应如下所示:

import sys
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio, GObject


class Application(Gtk.Application):
    def __init__(self):
        app_id = "org.iea.etc"
        flags = Gio.ApplicationFlags.FLAGS_NONE

        super(Application, self).__init__(application_id=app_id, flags=flags)

    def do_activate(self):
        # c.Controller(m.Model(), v.View(application=self))
        Controller(None, View(application=self))

    def do_startup(self):
        Gtk.Application.do_startup(self)


class Controller(object):
    def __init__(self, model, view):
        self._model = model
        self._view = view

        self._view.connect('switch_serial_toggled',
                           self._on_switch_serial_toggled)

        self._view.show_all()

    def _on_switch_serial_toggled(self, widget, active):
            if active is True:
                print('Switch ON')
            else:
                print('Switch OFF')


class View(Gtk.ApplicationWindow):
    __gsignals__ = {
        'switch_serial_toggled': (GObject.SIGNAL_RUN_FIRST, None, (bool,))
    }

    def __init__(self, **kw):
        super(View, self).__init__(**kw)

        self._switch_serial = Gtk.Switch()
        self._switch_serial.connect("notify::active", self.on_switch_serial_toggled)

        self.add(self._switch_serial)

    def on_switch_serial_toggled(self, obj, pspec):
        self.emit('switch_serial_toggled', self._switch_serial.get_active ())


if __name__ == '__main__':
    app = Application()
    exit_status = app.run(sys.argv)
    sys.exit(exit_status)

导致类似这样的事情:

enter image description here

PS :请注意,在步骤2中,obj是您连接信号处理程序的对象,类似于self._switch_serial。这意味着您可以使用obj.get_active ()代替:

def on_switch_serial_toggled(self, obj, pspec):
    self.emit('switch_serial_toggled', obj.get_active ())