【问题标题】:How do I listen for a DBus signal in a GTK (python 3, Gio) app?如何在 GTK (python 3, Gio) 应用程序中收听 DBus 信号?
【发布时间】:2018-08-17 18:10:53
【问题描述】:

我正在尝试让我的 GTK 应用响应网络连接状态的变化。我的方法就是我在问题中所说的:Listen on a (NetworkManager) DBus signal。

我有一个使用 python-gi 的 python3 GTK 应用程序(我应该添加一个非常小的应用程序)。 据我所知,python-dbus(又名“import dbus”)已被弃用,我想通过 python-gi 使用 Gio。

我有一个较旧的脚本,它在系统 DBus 上侦听我感兴趣的信号,它使用“import dbus”和以下代码:

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
bus.add_signal_receiver(NMSignalHandler,
                        dbus_interface=NM_INTERFACE,
                        signal_name='StateChanged')

(后跟一个 gobject.MainLoop().run())

我认为将“移植”到 Gio 相对简单,但即使阅读了两个小时的文档,我也不知道该怎么做。 任何帮助将不胜感激。

我已经尝试过使用 Gio.NetworkMonitor.get_default() 及其“网络更改”信号,但它似乎报告 net_available(第二个参数)始终为真,默认监视器似乎没有报告合理的结果要么。

我将非常感谢任何帮助。

【问题讨论】:

    标签: python linux gtk gio networkmanager


    【解决方案1】:

    要使用 python-gi 执行与 python-dbus 脚本等效的操作,以下内容对我有用:

    from gi.repository import GLib, Gio
    
    
    def network_changed_hndlr(network_monitor, network_available):
        print(network_monitor)
        print(network_available)
    
    
    default = Gio.NetworkMonitor.get_default()
    default.connect('network-changed', network_changed_hndlr)
    mainloop = GLib.MainLoop()
    try:
        mainloop.run()
    except KeyboardInterrupt:
        mainloop.quit()
    

    这是使用位于以下位置的文档: https://lazka.github.io/pgi-docs/Gio-2.0/structs/NetworkMonitor.html

    NetworkManager 有更多的对象路径和接口。

    例如,如果我查看这个的输出 busctl tree org.freedesktop.NetworkManager 我可以监控 48 个项目。

    如果我想监控活动连接的输出,应该是:

    from gi.repository import GLib, Gio
    
    ACTIVE_IFACE = 'org.freedesktop.NetworkManager.Connection.Active'
    
    
    def active_network_hndlr(dbus_proxy, properties_changed, properties_removed):
        props = properties_changed.unpack()
        print(props)
    
    
    def network_proxy(connection):
        """
        Provide proxy for comfortable and pythonic method calls
        """
        return Gio.DBusProxy.new_for_bus_sync(
                bus_type=Gio.BusType.SYSTEM,
                flags=Gio.DBusProxyFlags.NONE,
                info=None,
                name='org.freedesktop.NetworkManager',
                object_path=connection,
                interface_name=ACTIVE_IFACE,
                cancellable=None)
    
    net_mngr = network_proxy('/org/freedesktop/NetworkManager/ActiveConnection/8')
    net_mngr.connect('g-properties-changed', active_network_hndlr)
    
    mainloop = GLib.MainLoop()
    try:
        mainloop.run()
    except KeyboardInterrupt:
        mainloop.quit()
    
    

    DBusProxy 承担了大部分繁重的工作。这记录在: https://lazka.github.io/pgi-docs/Gio-2.0/classes/DBusProxy.html

    【讨论】:

      猜你喜欢
      • 2016-09-16
      • 2016-07-16
      • 2021-05-23
      • 2012-10-14
      • 2015-03-11
      • 2019-05-16
      • 2016-09-08
      • 1970-01-01
      • 2016-04-20
      相关资源
      最近更新 更多