gpt4 book ai didi

c++ - 如何在不阻塞主线程的情况下使用 Qt-Dbus 绑定(bind)

转载 作者:可可西里 更新时间:2023-11-01 16:38:11 28 4
gpt4 key购买 nike

我的目标是使用 Qt's DBus bindings 创建一个库.

我试图创建一个 Qt 应用程序,但没有在主线程中启动 QEventLoop(由 QCoreApplication 类提供)。

这是一个简约的应用程序示例,使用 QT-4.6.2 版本可以正常工作,但使用 QT-4.8 或更高版本会阻止内省(introspection)。

DBusHandler.hpp

#pragma once
#include <iostream>
#include <QtCore/QThread>
#include <QtCore/QtCore>
#include <QtDBus/QDBusInterface>

class DBusHandler : public QThread
{
Q_OBJECT;

private:
void run(void)
{
QDBusConnection connection = QDBusConnection::sessionBus();

connection.registerService("my.qdbus.example");
connection.registerObject("/", this, QDBusConnection::ExportAllSlots);
exec();
}

public:
DBusHandler(void) {}
virtual ~DBusHandler(void) {}

void stop(void)
{
QDBusConnection connection = QDBusConnection::sessionBus();

connection.unregisterObject("/");
connection.unregisterService("my.qdbus.example");
connection.disconnectFromBus(connection.name());
QThread::quit();
}

public slots:
void remoteCall(QByteArray message)
{
std::cout << "Message size: " << message.size() << std::endl;
}
};

main.cpp

#include "DBusHandler.hpp"

int main(int ac, char **av)
{
QCoreApplication app(ac, av);
DBusHandler handler;

handler.moveToThread(&handler);

handler.start();
while (not handler.isRunning());

// app.exec();
sleep(10); // Gives time to call using the command line: "qdbus my.qdbus.example / local.DBusHandler.remoteCall a_message"

handler.stop();
while (handler.isRunning());
}

正如您在 main.cpp 文件中看到的,app.exec() 被注释掉了,但应用程序在 QT-4.8 或更高版本上运行良好(5.3.0).

我的问题如下:是否可以在 Qt- 4.8 还是 5.3?

最佳答案

背景:有个私有(private)类叫QDBusConnectionPrivate它继承自 QObject 并处理所有网络。不幸的是,如果你看qdbusconnection.cpp:1116您会看到 Qt 将 moveToThread 硬编码为 QCoreApplication::instance()

您可能应该提交增强请求以允许用户创建使用用户指定线程或事件循环的 QDBusConnection。请参阅下面的更新。

与此同时,如果您愿意做一些危险的事情,您可以通过创建自己的 QDbusConnection 子类(我将我的命名为 SpecializedDBusConnection) 将 QThread 作为您希望将 QDbusConnectionPrivate 实例移动到的位置的第三个参数。然后使用该类创建连接而不是默认的 QDbusConnection::sessionBus()

因为这是使用一些私有(private)类,它需要包含一些私有(private)头文件(在下面的代码中注明),这反过来将尝试包含各种 dbus 库头,这将需要修改 INCLUDEPATH 包含 dbus 库的项目包含路径。

我已经验证这适用于 Qt 5.3.0 和 Qt 4.8.6。

更新:Qt 5.6, QtDBus was refactored to use threads用于传入/传出消息处理;不再阻塞主线程!

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]

关于c++ - 如何在不阻塞主线程的情况下使用 Qt-Dbus 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24058519/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com