qdbusxml2cpp generated properties with NOTIFY signals
-
First, it seems that qdbusxml2cpp does not generate NOTIFY signals. Is there a way to get it to do that? Being able to specify a signal with an annotation of some kind seems reasonable. Is there a technical reason why this is not available? This seems like a fairly large gap in DBus and QML integration. As it is, we will likely have to hand code our QDbusAbstractInterface classes, rather than using those generated by qdbusxml2cpp.
-
@greenroom Here is an example to make my question more clear: given the following DBus interface xml
<!-- SpeedRpm The current handpiece speed in RPM. --> <property name="speedRpm" type="q" access="read"/>
the following code is generated
Q_PROPERTY(ushort speedRpm READ speedRpm) inline ushort speedRpm() const { return qvariant_cast< ushort >(property("speedRpm")); }
Why can't qdbusxml2cpp generate this code
Q_PROPERTY(ushort speedRpm READ speedRpm NOTIFY speedRpmChanged) inline ushort speedRpm() const { return qvariant_cast< ushort >(property("speedRpm")); } ... signals: void speedRpmChanged(ushort speed);
-
Hi,
Just an educated guess: there's no reason from your description to add a signal. You have a read only property. If you want to have an additional signal then your interface declaration should state that as well.
Not all Qt properties have notification signal.
-
I understand you need. What I am saying is that you likely need to make your interface declaration more complete in order for the notify signal to be generated.
-
It's missing the signal part.
-
Has anyone figured out a way to get qdbusxml2cpp to generated properties with the NOTIFY signal?
I have an interface which I defined and it expressly says that the property has a change signal, but when I create an XML from it and use that XML to generate a proxy class for the interface it does not expose the NOTIFY signal (although the signal is defined with QT_SIGNAL)...
Here is the original Interface Class:
class benchInterface : public QObject { Q_OBJECT; Q_CLASSINFO("D-Bus Interface", "com.cana.bench") Q_PROPERTY(uchar gpioa READ gpioa WRITE setGpioa NOTIFY gpioaChanged) Q_PROPERTY(QString state READ getState WRITE setState NOTIFY stateChanged) public: benchInterface(QObject *parent = nullptr); virtual ~benchInterface(); public slots: bool startProcess(QString data); void quit(); signals: void processComplete(QString data); void processFailed(int errorcode); void gpioaChanged(); void stateChanged(); private slots: void onTimer(); private: uchar gpioa(); void setGpioa(uchar value); void setState(QString newState); QString getState(); QString processData; QString state = "Idle"; std::unique_ptr<cana::interface::i2c::i2c> i2c2_controller; std::unique_ptr<MCP23017> mcp23017; };
So I have a property
state
which is aQString
which has a notify signalstateChanged()
. The XML produced fromqdbuscpp2xml
is :<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node> <interface name="com.cana.bench"> <property name="gpioa" type="y" access="readwrite"/> <property name="state" type="s" access="readwrite"/> <signal name="processComplete"> <arg name="data" type="s" direction="out"/> </signal> <signal name="processFailed"> <arg name="errorcode" type="i" direction="out"/> </signal> <signal name="gpioaChanged"> </signal> <signal name="stateChanged"> </signal> <method name="startProcess"> <arg type="b" direction="out"/> <arg name="data" type="s" direction="in"/> </method> <method name="quit"> </method> </interface> </node>
But the resulting proxy class does not expose the NOTIFY signal:
/* * Proxy class for interface com.cana.bench */ class ComCanaBenchInterface : public QDBusAbstractInterface { Q_OBJECT public: static inline const char *staticInterfaceName() { return "com.cana.bench"; } public: ComCanaBenchInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); ~ComCanaBenchInterface(); Q_PROPERTY(uchar gpioa READ gpioa WRITE setGpioa) inline uchar gpioa() const { return qvariant_cast<uchar>(property("gpioa")); } inline void setGpioa(uchar value) { setProperty("gpioa", QVariant::fromValue(value)); } Q_PROPERTY(QString state READ state WRITE setState) inline QString state() const { return qvariant_cast<QString>(property("state")); } inline void setState(const QString &value) { setProperty("state", QVariant::fromValue(value)); } public Q_SLOTS: // METHODS inline QDBusPendingReply<> quit() { QList<QVariant> argumentList; return asyncCallWithArgumentList(QStringLiteral("quit"), argumentList); } inline QDBusPendingReply<bool> startProcess(const QString &data) { QList<QVariant> argumentList; argumentList << QVariant::fromValue(data); return asyncCallWithArgumentList(QStringLiteral("startProcess"), argumentList); } Q_SIGNALS: // SIGNALS void gpioaChanged(); void processComplete(const QString &data); void processFailed(int errorcode); void stateChanged(); };
Is there something I am missing? When I manually add the NOTIFY to the generated proxy class then the property works correctly (using from QML).
Thank you,
Michael Uman
Sr Firmware Engineer
Cana Technologies -
Judging from the source code of qdbusxml2cpp: it cannot generate NOTIFY declarations for properties at all.
Christian