我正在编写一个类似RPC的程序,使用Qt信号槽,当使用客户端程序调用服务器时,会执行一个函数,我需要在QtableWidget上打印这个函数的值,所以我使用
emit
在这个函数中传输信号,但是我发现槽函数没有执行。这似乎与多线程有关。
更新:我发现我把代码弄乱了,这里简化一下。 我使用静态类方法来发出信号,因此代码看起来有点棘手。
// service.cpp file
#include "service.h"
multipleService* multipleService::getInstance = nullptr;
int add(int a, int b) {
return a + b;
}
multipleService::multipleService() {
getInstance = this; // for static method to emit signal
bool ok = connect(this, &multipleService::internalMessageOutput, this, &multipleService::messageOutputFunc, Qt::AutoConnection);
}
// implement service
void multipleService::AddService(ServiceType::Request& request, ServiceType::Response& response) {
// do some stuff ... get response
emit getInstance->internalMessageOutput(QString(response));
}
void multipleService::messageOutputFunc(QString msg) {
emit getInstance->messageOutput(msg);
}
// service.h file
#pragma once
#include <stdio.h>
#include <string.h>
// some declarations
class multipleService :public QObject {
Q_OBJECT
public:
multipleService();
~multipleService();
static void AddService(ServiceType::Request& request, ServiceType::Response& response);
void messageOutputFunc(QString);
private:
static multipleService* getInstance;
signals:
void messageOutput(QString);
void internalMessageOutput(QString);
};
在
mainwindow.cpp
文件中,我使用 create_service
表现得像 RPC 中的服务器。这实际上效果很好。一旦 emit getInstance->internalMessageOutput(QString(response));
执行,信号函数就会执行。
//mainwindow.cpp in main thread
multipleService* s = new multipleService();
connect(s, &multipleService::messageOutput, this, &serviceThread::outputMessage);
auto service = node.create_service<ServiceType>(service_name, multipleService::AddService, qoS);
但是我想创建一个多线程,所以我改变了代码
// mainwindow.cpp file in main thread
QThread* thread = new QThread; //create a thread
serviceThread* myThread = new serviceThread(this);// create a class which derives from QObject and move it to the thread
//connect start signal with a lambda func
connect(thread, &QThread::started, myThread, [&myThread, SERVICE_NAME]()
{ std::string a = SERVICE_NAME;
char* AddServiceName = (char*)a.data();
myThread->createService("NODE", AddServiceName, 10);
});
// start a thread and this will call the slot func
thread->start();
myThread->moveToThread(thread);
我创建了一个
serviceThread.cpp
和 new serviceThread
并将其移动到一个线程以支持多线程,但是 emit getInstance->internalMessageOutput(QString(response))
,槽函数不执行。
//serviceThread.cpp file
void serviceThread::createService(const char* nodeName, const char* service_name, int historyDepth) {
// do some declaration
multipleService* s = new multipleService();
connect(s, &multipleService::messageOutput, this,
&serviceThread::outputMessage);
auto service = node.create_service<ServiceType>(service_name,
multipleService::AddService, qos);
if (service) {
service->start();
}
else {
// error
return;
}
while (true)
{
if (QThread::currentThread()->isInterruptionRequested())
{
break;
}
}
}
我尝试将连接类型更改为
Qt::QueuedConnection
,但这也失败了。我还在该行设置了一个断点,它确实执行了。
我立即看到的问题之一是
mainwindow.cpp
代码:
QThread* thread = new QThread; //create a thread
serviceThread* myThread = new serviceThread(this);// create a class which derives
...
myThread->moveToThread(thread); // this will silently fail.
如果你在网站上查找文档,你必须注意,他们提到。您无法移动父级的
QObject
,并且根本无法移动QWidget
。由于 QThread
是 QObjects
,因此 myThread
无法移动 - 它现在是主窗口的父窗口,主窗口是主线程的一部分。
我通常的方法是拥有一个
QObject
派生类,我们称之为 Manager
,我会将其移动到工作线程,将 QThread
的适当信号连接到 Manager
的插槽。 Manager
将创建其余部分并充当他的孩子的代理和父母。