python - 如何在 GTK(python 3、Gio)应用程序中监听 DBus 信号?

标签 python linux gtk gio networkmanager

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

我有一个 python3 GTK 应用程序(一个非常小的应用程序,我应该补充一下),使用 python-gi。 据我所知,由于 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-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 有更多的对象路径和接口(interface)。

例如,如果我看一下这个的输出 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

关于python - 如何在 GTK(python 3、Gio)应用程序中监听 DBus 信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51900869/

相关文章:

python - 如何防止在 YAML 中重新定义 key ?

linux - 使用 Cloudflare 时,NGINX 速率限制不起作用。我可以用一个简单的 `ab` 命令关闭我的网站

linux - 删除文件名中两次出现的字符串之间的字符串

c++ - 如何翻译 GTK+ 应用程序?

python - 什么是适合 pygtk 应用程序的嵌入式浏览器?

python - PLY 中的 IF 语句

python - 需要澄清 - 使用列表的 Python For 循环

python - 无法从 anaconda 打开 jupyter 笔记本

linux - 使用 SSH 时转义引号

python-3.x - 如何在 GTK 中创建带有弹出菜单的 "HeaderMenu"?