PyQt5: How to get/set properties using QtDBus

616 views Asked by At

I'm trying to communicate with SMPlayer using its D-Bus interface "org.mpris.MediaPlayer2". Calling methods works fine. For example:

smp = QDBusInterface(r'org.mpris.MediaPlayer2.smplayer', "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player")
smp.call("Pause")
smp.call("Seek",QDBusArgument(int(value_in_ms)*1000, QMetaType.LongLong))

I tried both of these variants below I found online, but the result is None for the first variant (this how I think it should be done), and I get the error No such method 'Rate' in interface 'org.mpris.MediaPlayer2.Player' at object path '/org/mpris/MediaPlayer2'(signature '') for the second one:

res = smp.property("Rate")
res = smp.call("Rate")

I verified that the these properties actually exist. I can read them using dbus-send or qdbus on the command-line. Any idea what I am doing wrong?

1

There are 1 answers

1
ekhumoro On BEST ANSWER

There are several problems with your code. You're using the wrong interface to get/set the properties, and the argument types are specified incorrectly. Also, you are trying to use property(), which is an inherited QObject method with no relevance to dbus.

The interactive demo script below shows how to get and set the SMPLayer Rate property (the format of which is documented here). Note that it is essential that QDBusVariant is used to specify the value when setting the property:

from PyQt5 import QtDBus

service = 'org.mpris.MediaPlayer2.smplayer'
path = '/org/mpris/MediaPlayer2'
iface = 'org.mpris.MediaPlayer2.Player'
props = 'org.freedesktop.DBus.Properties'

smp = QtDBus.QDBusInterface(service, path, props)
msg = smp.call('Get', iface, 'Rate')
print(f'Current Rate: {msg.arguments()[0]}\n')

rate = input('Enter New Rate: ')

try:
    rate = float(rate)
except ValueError:
    print(f'ERROR: invalid rate value: {rate!r}')
else:
    msg = smp.call('Set', iface, 'Rate', QtDBus.QDBusVariant(rate))
    if msg.errorName():
        print('ERROR:', msg.errorMessage())
    else:
        msg = smp.call('Get', iface, 'Rate')
        print(f'Set New Rate: {msg.arguments()[0]}')

Output:

$ python demo.py
Current Rate: 1.0

Enter New Rate: 1.25
Set New Rate: 1.25