Search code examples
pythonqtpysidedbuskde-plasma

How can I trigger shutdown or logout in KDE Plasma via QDbus in Python?


A KDE Plasma session can be given the signal to log out using the following in a terminal window:

qdbus6 org.kde.Shutdown /Shutdown org.kde.Shutdown.logout

or simply

qdbus6 org.kde.Shutdown /Shutdown logout

This immediately logs me out when I run it. Similar methods exist on the same Path for shutting down and restarting.

I would like to trigger the same thing from a Python script.

The QtDBus module in Qt enables sending messages over the DBus system. It is available in PySide6 and I am trying to send the exact same signal from Python:

from PySide6.QtDBus import QDBusConnection, QDBusMessage

connection = QDBusConnection.sessionBus()
message = QDBusMessage.createTargetedSignal("org.kde.Shutdown", "/Shutdown", "org.kde.Shutdown", "logout")
print(connection.send(message))

If this code is run as a script, or entered into a Python interpreter, it returns True, but returns False if the script is run as root using sudo, which kind of implies to me that org.kde.Shutdown is available via the connection made with sessionBus() i.e. the connection is to the user session bus.

So why doesn't Plasma log out when I run the script?

Any help much appreciated.


Solution

  • Your qdbus command isn't sending a signal, it is sending a method call. They're distinct message types in D-Bus (and generally used in opposite ways – a typical signal would be sent "from" an object and interface that the sender has published; it is not directed towards any object at the recipient.) See documentation.

    Method calls always cause a reply, so you should send them using call() instead of send().