Qt DBus 连接不使用 SLOT 参数中的 typedef

Posted

技术标签:

【中文标题】Qt DBus 连接不使用 SLOT 参数中的 typedef【英文标题】:Qt DBus connect not working with typedef in SLOT arguments 【发布时间】:2020-04-18 10:01:11 【问题描述】:

我可以使用 QDBusConnection::connect 和旧式 SLOT 语法将 DBus 信号连接到 Qt 插槽:

#pragma GCC diagnostic push
#   pragma GCC diagnostic ignored "-Wconversion"
#   include <QCoreApplication>
#   include <QDBusConnection>
#   include <QDBusMetaType>
#   include <QDebug>
#   include <QMap>
#   include <QString>
#   include <QVariant>
#pragma GCC diagnostic pop

using PropertyDictionary = QMap<QString, QVariant>;
Q_DECLARE_METATYPE(PropertyDictionary)

class MyLogger : public QObject

    Q_OBJECT

public slots:

    void log(QString const& interface, QMap<QString, QVariant> const& properties)
    
        logTypedef(interface, properties);
    

    void logTypedef(QString const& interface, PropertyDictionary const& properties)
    
        qDebug() << "interface = " << interface;
        qDebug() << "properties = " << properties;
    
;

int main(int argc, char* argv[])

    qDBusRegisterMetaType<PropertyDictionary>();

    QCoreApplication appargc, argv;
    MyLogger logger;
    auto const connected
    
        QDBusConnection::systemBus().connect
        (
            "org.freedesktop.timedate1",
            "/org/freedesktop/timedate1",
            "org.freedesktop.DBus.Properties",
            "PropertiesChanged",
            &logger,
            // SLOT(log(QString, QMap<QString, QVariant>)) // works
            SLOT(logTypedef(QString, PropertyDictionary)) // assert fails
        )
    ;
    Q_ASSERT(connected);

    return app.exec();


#include "DBusTimezoneApp.moc"

如果我对插槽使用QMap&lt;QString, QVariant&gt; 参数,则connect 调用成功并且接收到DBus 信号。如果我使用PropertyDictionary typedef,它会失败。

我知道 C++,但我是 moc 魔法的新手,所以希望能得到您的帮助。

我正在使用来自 Ubuntu 存储库的 Ubuntu 18.04、Qt 5.9.5 构建,使用

/usr/lib/qt5/bin/moc  -I /usr/include/x86_64-linux-gnu/qt5 -I /usr/include/x86_64-linux-gnu/qt5/QtCore -I /usr/include/x86_64-linux-gnu/qt5/QtDBus -I /usr/include/x86_64-linux-gnu/qt5/QtNetwork  -i DBusTimezoneApp.cxx -o DBusTimezoneApp.moc
g++ -Wall -Wextra -Wconversion -Werror -pedantic -I /usr/include/x86_64-linux-gnu/qt5 -I /usr/include/x86_64-linux-gnu/qt5/QtCore -I /usr/include/x86_64-linux-gnu/qt5/QtDBus -I /usr/include/x86_64-linux-gnu/qt5/QtNetwork   -std=c++17 -fPIC -O0 -g3 -c DBusTimezoneApp.cxx
g++ -o DBusTimezoneApp DBusTimezoneApp.o -l Qt5Core -l Qt5DBus -l Qt5Network

【问题讨论】:

【参考方案1】:

您必须使用 qRegisterMetaType 注册 PropertyDictionary:

// ...
qDBusRegisterMetaType<PropertyDictionary>();
qRegisterMetaType<PropertyDictionary>("PropertyDictionary");
// ...

【讨论】:

以上是关于Qt DBus 连接不使用 SLOT 参数中的 typedef的主要内容,如果未能解决你的问题,请参考以下文章

QT 用比 SLOT 更少的参数连接一个 SIGNAL

关于QT中的signal 和 slot 中带参数问题

这个 Qt DBus 信号连接代码是不是正确?

没有 SLOT 宏的 Qt 连接

dbus会话连接:用qt槽连接dbus信号,怎么做?

QT使用connect中SLOT的函数能加参数吗