How to use Qt-Dbus bindings without blocking the main thread

前端 未结 1 827
离开以前
离开以前 2021-01-12 01:40

My goal is to create a library using the Qt\'s DBus bindings.

I tried to create a Qt application without launching the QEventLoop (provided by the

1条回答
  •  自闭症患者
    2021-01-12 02:04

    Background: There is a private class called QDBusConnectionPrivate which inherits from QObject and handles all networking. Unfortunately, if you look at qdbusconnection.cpp:1116 you'll see that Qt hard codes the moveToThread to QCoreApplication::instance().

    You should probably submit an enhancement request to allow the user to create a QDBusConnection that uses a user specified thread or event loop. See update below.

    In the meantime, if you're comfortable doing some dangerous things, you can hack it in yourself by creating your own QDbusConnection subclass (I called mine SpecializedDBusConnection) that takes QThread as a third argument of where you want the QDbusConnectionPrivate instance to be moved to. Then use that class to create the connection instead of the default QDbusConnection::sessionBus().

    As this is using some private classes, it requires the inclusion of some private header files (noted in the code below) which in turn will attempt to include various dbus library headers which will necessitate the modifying of INCLUDEPATH of the project to include the dbus library include path.

    I've verified this works on Qt 5.3.0 and Qt 4.8.6.

    Update: In Qt 5.6, QtDBus was refactored to use threads for incoming/outgoing message processing; no more blocking of the main thread!

    DBusHandler.hpp

    #pragma once
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include "/path/to/Qt5.3.0/5.3/Src/qtbase/src/dbus/qdbusconnection_p.h"
    
    class SpecializedDBusConnection : public QDBusConnection {
        const char *ownName;
    public:
        inline SpecializedDBusConnection(BusType type, const char *name, QThread *thread)
            : QDBusConnection(connectToBus(type, QString::fromLatin1(name))), ownName(name)
        {
            if (QDBusConnectionPrivate::d(*this)) {
                QDBusConnectionPrivate::d(*this)->moveToThread(thread);
            }
        }
    
        inline ~SpecializedDBusConnection()
        { disconnectFromBus(QString::fromLatin1(ownName)); }
    };
    
    class DBusHandler : public QThread
    {
        Q_OBJECT;
    
    private:     
        void run(void)
        {
            QDBusConnection connection = SpecializedDBusConnection(QDBusConnection::SessionBus, "qt_default_session_bus", this);
    
            connection.registerService("my.qdbus.example");
            connection.registerObject("/", this, QDBusConnection::ExportAllSlots);
    
            exec();
        }
    [snip]
    

    0 讨论(0)
提交回复
热议问题