Qt 线程事件循环不发送自创建的信号

问题描述

我想创建一个 GUI 应用程序,它可以与连接到我的 PC 的设备进行通信。因此,我想将 GUI 处理从设备通信拆分到不同的线程,以避免阻塞 GUI(一个控制器线程和一个 GUI 线程)。我已经用 Python 中的 PyQt5 做到了这一点。因为我现在想用 C++ 创建一个应用程序,所以我用与在 PyQt 中相同的方式对其进行了编程。但结果并不相同。线程之间的通信应该由 Qt 的信号槽系统处理,该系统应该是线程安全的。所以我创建了我的 GUI 对象(继承了 QWidget 类)和我的控制器对象(继承了 QObject),我创建了一个 QThread 的实例,连接了 gui 和控制器对象的信号和插槽,将控制器对象移动到新创建的线程,启动线程,然后执行 QApplication 对象。我现在遇到的问题是,由 Qt-Objects(即 QPushButton)创建的事件由控制器线程处理但自创建信号不是(发射)。这是我的代码的重要部分:

GUI.h:

#include <QtWidgets/qwidget.h>
#include <QtWidgets/qpushbutton.h>
#include <QtWidgets/qcomboBox.h>
#include <QtWidgets/qlayout.h>
#include <deque>
#include <string>

class myGUI : public QWidget
{
   Q_OBJECT
public:
   myGUI(QWidget * parent=nullptr);
   virtual ~myGUI() = default;
   void load_settings();
signals:
   void refreshPorts(void);
   void connect(std::string port);
public slots:
   void onPortsRefreshed(std::deque<std::string> port_list);
protected:
   QHBoxLayout * hBox;
   QPushButton * refresh_ports_btn;
   QPushButton * connect_btn;
   QComboBox *   port_cbx;

   void on_connect_pressed();
}

GUI.cpp:

#include "GUI.h"

myGUI::myGUI(QWidget * parent)
   : QWidget(parent)
{
   this->hBox = new QHBoxLayout;
   this->port_cbx = new QComboBox;
   this->refresh_ports_btn = new QPushButton("Refresh ports");
   this->connect_btn = new QPushButton("connect");
   this->hBox->addWidget(this->port_cbx);
   this->hBox->addWidget(this->refresh_ports_btn);

   this->setLayout(this->hBox);

   /* connecting the signals and slots */
   QObject::connect(this->refresh_ports_btn,&QPushButton::clicked,this,&myGUI::refreshPorts);
   QObject::connect(this->connect_btn,&myGUI::on_connect_pressed);
}

void myGUI::load_settings()
{
   emit this->refreshPorts();
}

void myGUI::on_connect_pressed()
{
   std::string port = this->port_cbx->currentText().toStdString();
   if(!port.empty())
   {
      emit this->connect(port);
   }
}

void myGUI::onPortsRefreshed(std::deque<std::string> port_list)
{
   this->port_cbx.clear();
   for(auto &elem : port_list)
   {
      this->port_cbx->addText(QString::fromStdString(elem));
   }
}

Controller.h:

#include <QtCore/qobject.h>
#include <deque>
#include <string>

class myController : public QObject
{
   Q_OBJECT
public:
   myController(QObject * parent = nullptr);
   virtual ~myController() = default;

signals:
   void ports_refreshed(std::deque<std::string> );

public slots:
   void on_refresh_ports(void);
   void on_connect(void);
}

控制器.cpp

#include "Controller.h"

myController::myController(QObject * parent)
   : QObject(parent)
{

}

void myController::on_refresh_ports()
{
   auto port_list = std::deque<std::string>();
   port_list.push_back(std::string("COM1"));
   port_list.push_back(std::string("COM4"));
   emit this->ports_refreshed(port_list);
}

void myController::on_connect(std::string port)
{
   /* connect to com-port */
}

main.cpp:

#include "GUI.h"
#include "Controller.h"
#include <QtWidgets/qapplication.h>
#include <QtCore/qthread.h>

int main(int argc,char * argv[])
{
   QApplication app(argc,argv);
   myGUI * gui = new myGUI;
   myController * ctrl = new Controller;
   QTread ctrl_thrd = new QThread;

   QObject::connect(gui,&myGUI::refreshPorts,ctrl,&myController::on_refresh_ports);
   QObject::connect(gui,&myGUI::connect,&myController::on_connect);
   QObject::connect(ctrl,&myController::ports_refreshed,gui,&myGUI::onPortsRefreshed);

   ctrl_thrd->start();
   ctrl->movetoThread(ctrl_trhd);

   gui->load_settings();

   gui->show();

   return app.exec();
}

应用程序启动但从未调用方法 refresh_ports(无论是在调用 load_settings 还是单击“刷新端口”时。当我将 QPushButtons 的“clicked”事件与控制器对象。当我删除 ctrl_thrd 并在单个线程中运行它时,应用程序工作正常。 我在其他问题上对我的问题进行了大量研究,但没有找到答案。 (大多数是关于从 QThread 继承而不是将对象移动到线程时错误的使用)。 像这样的代码在 PyQt 中总是有效的。那么我做错了什么?

提前致谢!

P.S.:示例中省略了对象删除代码

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)