在Qt信号槽程序中,槽函数发送后没有执行

问题描述 投票:0回答:1

我正在编写一个类似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
,但这也失败了。我还在该行设置了一个断点,它确实执行了。

c++ qt rpc signals-slots data-distribution-service
1个回答
0
投票

我立即看到的问题之一是

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
将创建其余部分并充当他的孩子的代理和父母。

© www.soinside.com 2019 - 2024. All rights reserved.