连接到 DBus 信号 - 正确语法 - PySide6

问题描述 投票:0回答:2

您能帮助我使用正确的语法来连接 DBus 信号吗?

这是我的众多尝试之一,它至少运行并匹配文档中的签名

from PySide6 import QtDBus
from PySide6.QtCore import Q
from PySide6.QtWidgets import QMainWindow

class MainWindow(QMainWindow):
    __slots__ = ["__mainwidget"]
    __mainwidget:QWidget

    def __init__ (self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        service = 'org.freedesktop.DBus'
        path = '/org/freedesktop/DBus'
        iface = 'org.freedesktop.DBus'
        conn = QtDBus.QDBusConnection.systemBus()
        conn.connect(service, path, iface, "NameOwnerChanged", self, "nochangeslot")
        #smp = QtDBus.QDBusInterface(service, path, iface, connection=QtDBus.QDBusConnection.systemBus()


    def nochangeslot(self, arg:object) -> None:
        print(arg)
        pass

但是它不起作用,并且将插槽作为字符串看起来很奇怪......

在输出中我看到:

qt.dbus.integration: Could not connect "org.freedesktop.DBus" to ochangeslot

请考虑这是 PySide6 问题而不是 PyQt5 问题,调用的签名略有不同,并且我的代码不会像 stackoverflow 上的类似主题那样挂起。

预先感谢您的帮助!

python pyside dbus pyside6
2个回答
1
投票

该示例有两个问题,第一个问题已在此处得到解答:

因此,您首先只需将以下行添加到示例中:

conn.registerObject('/', self)

第二个问题在 PyQt 中很容易解决(在上面链接的问题中清楚地显示)。然而,PySide 似乎仍在其 dbus API 中使用丑陋且容易出错的 C++ 语法,如果您不是 PyQt/PySide 的长期用户,这可能会使连接信号和插槽变得极其不直观。相比之下,PyQt 发送通用的QDBusMessage,这大大简化了事情,因为不需要事先知道签名的确切形式。为了说明差异,这里有两个基本的工作示例:

PyQt6

from PyQt6 import QtCore, QtWidgets, QtDBus

class MainWindow(QtWidgets.QMainWindow):
    def __init__ (self):
        super().__init__()
        service = 'org.freedesktop.DBus'
        path = '/org/freedesktop/DBus'
        iface = 'org.freedesktop.DBus'
        conn = QtDBus.QDBusConnection.systemBus()
        conn.registerObject('/', self)
        conn.connect(service, path, iface, 'NameAcquired', self.nochangeslot)

    @QtCore.pyqtSlot(QtDBus.QDBusMessage)
    def nochangeslot(self, msg):
        print(f'signature: {msg.signature()!r}, '
              f'arguments: {msg.arguments()!r}')

app = QtWidgets.QApplication(['Test'])
window = MainWindow()
window.show()
app.exec()

PySide6

from PySide6 import QtCore, QtWidgets, QtDBus

class MainWindow(QtWidgets.QMainWindow):
    def __init__ (self):
        super().__init__()
        service = 'org.freedesktop.DBus'
        path = '/org/freedesktop/DBus'
        iface = 'org.freedesktop.DBus'
        conn = QtDBus.QDBusConnection.systemBus()
        conn.registerObject('/', self)
        conn.connect(service, path, iface, 'NameAcquired',
                     self, QtCore.SLOT('nochangeslot(QString)'))

    @QtCore.Slot(str)
    def nochangeslot(self, args):
        print(f'arguments: {args!r}')

app = QtWidgets.QApplication(['Test'])
window = MainWindow()
window.show()
app.exec()

0
投票

这是我最初帖子的完整解决方案,我在 QT/PySide 支持下运行了它,他们还承认了hangig bug 和 Python 崩溃:

import sys
from PySide6.QtWidgets import QMainWindow
from PySide6 import QtDBus, QtCore
from PySide6.QtCore import QLibraryInfo, qVersion, Slot
from PySide6.QtWidgets import QApplication, QMainWindow

class MainWindow(QMainWindow):

    def __init__ (self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        service = "org.freedesktop.DBus"
        path = "/org/freedesktop/DBus"
        iface = "org.freedesktop.DBus"
        conn = QtDBus.QDBusConnection.systemBus()

        #without this, the conn.connect call hangs, seems to be a bug, is already reported and fixed.
        conn.registerObject('/', self)

        conn.connect(service, path, iface, "NameOwnerChanged", self, QtCore.SLOT("nameownerchanged(QString, QString, QString)"))    
        pass

    @Slot(str, str, str)
    def nameownerchanged(self, arg1:str, arg2:str, arg3:str) -> None:
        print(arg1)
        print(arg2)
        print(arg3)
        pass

if __name__ == '__main__':
    print('Python {}.{}.{} {}'.format(sys.version_info[0], sys.version_info[1],
                                       sys.version_info[2], sys.platform))
    print(QLibraryInfo.build())
    app = QApplication(sys.argv)
    window = MainWindow()
    window.setWindowTitle(qVersion())
    window.resize(800, 480)
    window.show()
    sys.exit(app.exec())
© www.soinside.com 2019 - 2024. All rights reserved.