[PyQt] How to pass arguments in QDBusConnection connect() method - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: [PyQt] How to pass arguments in QDBusConnection connect() method (/thread-16613.html) |
How to pass arguments in QDBusConnection connect() method - Alfalfa - Mar-06-2019 I want to execute commands when some dbus signals are fired. Usually, I make a slot for each signals and it work just fine. However, in this case I need to attach signals dynamically, so a single slot must receive an argument in order to handle multiple signals. I was not able to use lambda like I would do for widgets signals. I tried combinations of all the commented approach below, and altough the connect method return True, the message is not delivered to the slot. #!/usr/bin/python3 import sys from PyQt5 import QtCore, QtWidgets, QtDBus SIGNALS = \ { "0": { "description": "Mute speaker on resume", "bus": "system", ## todo "service": "org.freedesktop.login1", "path": "/org/freedesktop/login1", "interface": "org.freedesktop.login1.Manager", "name": "PrepareForSleep", "exec": "amixer -D pulse sset Master mute" } } class Main(QtCore.QObject): def __init__(self, parent): super().__init__() self.bus = QtDBus.QDBusConnection.systemBus() for num in SIGNALS: service = SIGNALS[num]["service"] path = SIGNALS[num]["path"] interface = SIGNALS[num]["interface"] name = SIGNALS[num]["name"] cmd = SIGNALS[num]["exec"] if QtDBus.QDBusConnection.systemBus().interface().isServiceRegistered(service).value(): # connect(service, path, interface, name, signature, slot) #self.bus.connect(service, path, interface, name, "s", self._slot) # connect(service, path, interface, name, argumentMatch, signature, slot) self.bus.connect(service, path, interface, name, [cmd], "s", self._slot) #self.bus.connect(service, path, interface, name, [cmd], "o", self._slot) #@QtCore.pyqtSlot() #@QtCore.pyqtSlot(object) #@QtCore.pyqtSlot(list) @QtCore.pyqtSlot(str) def _slot(self, cmd): print(f"got '{cmd}'") if __name__== '__main__': app = QtWidgets.QApplication(sys.argv) daemon = Main(app) sys.exit(app.exec_()) RE: How to pass arguments in QDBusConnection connect() method - Alfalfa - Mar-07-2019 The problem was that the slot is meant to receive arguments from the signal, so in this case a boolean: #!/usr/bin/python3 import sys from PyQt5 import QtCore, QtWidgets, QtDBus class Main(QtWidgets.QMainWindow): def __init__(self, parent): super().__init__() service = "org.freedesktop.login1" if QtDBus.QDBusConnection.systemBus().interface().isServiceRegistered(service).value(): path = "/org/freedesktop/login1" interface = "org.freedesktop.login1.Manager" name = "PrepareForSleep" self.bus = QtDBus.QDBusConnection.systemBus() self.bus.connect(service, path, interface, name, self._slot) self.bus.connect(service, path, interface, name, "b", self._slotOverloaded) @QtCore.pyqtSlot() def _slot(self): print("Got 'PrepareForSleep' Signal") @QtCore.pyqtSlot(bool) def _slotOverloaded(self, data): print(f"Got '{data}' from 'PrepareForSleep' Signal") if __name__== '__main__': app = QtWidgets.QApplication([]) daemon = Main(app) sys.exit(app.exec_())Therefore the solution for my problem is to create an object for each signals-command pair: #!/usr/bin/python3 import sys from PyQt5 import QtCore, QtWidgets, QtDBus SIGNALS = \ { 0: { "description": "Mute speaker on resume", "bus": "system", "service": "org.freedesktop.login1", "path": "/org/freedesktop/login1", "interface": "org.freedesktop.login1.Manager", "name": "PrepareForSleep", "exec": "amixer -D pulse sset Master mute" } } class DBusSignalMonitor(QtCore.QObject): def __init__(self, parent, signal): super().__init__() service = signal["service"] path = signal["path"] interface = signal["interface"] name = signal["name"] bus = signal["bus"] self.cmd = signal["exec"] if bus == "session": if QtDBus.QDBusConnection.sessionBus().interface().isServiceRegistered(service).value(): parent.sessionBus.connect(service, path, interface, name, self._slot) elif bus == "system": if QtDBus.QDBusConnection.systemBus().interface().isServiceRegistered(service).value(): parent.systemBus.connect(service, path, interface, name, self._slot) @QtCore.pyqtSlot() def _slot(self): print(f"exec '{self.cmd}'") class DBusDaemon(QtCore.QObject): def __init__(self, parent): super().__init__() self.sessionBus = QtDBus.QDBusConnection.systemBus() self.systemBus = QtDBus.QDBusConnection.systemBus() self.signals = {} for s in SIGNALS: self.signals[s] = DBusSignalMonitor(self, SIGNALS[s]) if __name__== '__main__': app = QtWidgets.QApplication(sys.argv) daemon = DBusDaemon(app) sys.exit(app.exec_()) |