背景: 有一个私人课程叫QDBusConnectionPrivate它继承自 QObject 并处理所有网络。不幸的是,如果你看qdbusconnection.cpp:1116你会看到 Qt 硬编码了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.
同时,如果你愿意做一些危险的事情,你可以通过创建自己的东西来破解它QDbusConnection
子类(我称之为我的SpecializedDBusConnection
)这需要QThread
作为你想要的第三个参数QDbusConnectionPrivate
要移动到的实例。然后使用该类来创建连接而不是默认的连接QDbusConnection::sessionBus()
.
由于这是使用一些私有类,因此需要包含一些私有头文件(在下面的代码中注明),而这些文件又将尝试包含各种 dbus 库头文件,这将需要修改包含路径项目的包含 dbus 库的包含路径。
我已经验证这适用于 Qt 5.3.0 和 Qt 4.8.6。
Update: In Qt 5.6,QtDBus 被重构为使用线程用于传入/传出消息处理;不再阻塞主线程!
DBusHandler.hpp
#pragma once
#include <iostream>
#include <QtCore/QThread>
#include <QtCore/QtCore>
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusConnectionInterface>
#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]