问题描述
我想创建一个 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 中总是有效的。那么我做错了什么?
提前致谢!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)