赞
踩
原创文章,欢迎转载。转载请注明:转载自 祥的博客
原文链接:https://blog.csdn.net/humanking7/article/details/86071134
Qt自定义信号signals和emit信号
Qt
调用Matlab Engine
,但是Matlab Engine
打开太慢了,如果放在UI主线程
中会造成界面卡死,所以打算开一个线程去打开Matlab Engine
,当其打开后,向UI主线程
发送signal消息
,当UI主线程
的slot槽
接收到消息后
,就会将Matlab Engine
对应的Matlab Command Window对话框
嵌入到UI主线程
的界面中。
所以本文的所需解决的问题就是:
在一个线程中发送一个
自定义signal信号
,另一线程的slot槽
接收到消息后,进行相应
#include <QThread> #include <QDialog> #include "engine.h" class threadMatlab : public QThread { Q_OBJECT //自定义信号 signals: void openMatlabEngine(bool isOpenMatlabEngine); // 用于向主线程发送Matlab Engine是否打开的信号, 在.cpp中,没有进行定义,直接使用emit进行数据的发送 public: threadMatlab(QObject *parent); ~threadMatlab(); void setMatlabEngine(Engine** pEp);//将Matlab指针的指针传递给它 void quitThead();//退出线程 protected: void run(); private: QDialog* m_pParent = nullptr;//父窗口 bool m_isOpenMatlabEngine = false;//是否已经打开了Matlab Engine Engine** m_pEp = NULL; //指向指针的指针[定义Matlab engine类型指针,往后函数都要用它来指示目标] bool m_isQuit = false;//是否要退出 };
#include "threadMatlab.h" threadMatlab::threadMatlab(QObject *parent) : QThread(parent) { m_pParent = (QDialog*)parent; m_isOpenMatlabEngine = false; m_isQuit = false; } threadMatlab::~threadMatlab() { } void threadMatlab::setMatlabEngine(Engine** pEp) { m_pEp = pEp; } void threadMatlab::quitThead() { m_isQuit = true; } void threadMatlab::run() { while (true) { //是否要退出 if (m_isQuit) { break;//退出while } //打开Matlab Engine[如果没打开,就一直去打开,直到打开] if (false == m_isOpenMatlabEngine)//没有打开Matlab Engine { (*m_pEp) = engOpen(NULL); //启动Matlab Engine if ((*m_pEp) != NULL) {//打开成功 m_isOpenMatlabEngine = true; // 发送信号 emit openMatlabEngine(m_isOpenMatlabEngine); engSetVisible((*m_pEp), false);//不显示Matlab Cmd对话框 } else {//打开失败 m_isOpenMatlabEngine = false; // 发送信号 emit openMatlabEngine(m_isOpenMatlabEngine); } } } }
#include <QDialog> #include "ui_MatlabCmdDlg.h" #include<QWindow> #include <windows.h> #include <QDebug> #include <QCloseEvent> #pragma execution_character_set("utf-8") #include "threadMatlab.h" #include "engine.h" //附加依赖项[下面3行,可以直接在配置中设置] #pragma comment(lib,"libeng.lib") #pragma comment(lib,"libmx.lib") #pragma comment(lib,"libmex.lib") class MatlabCmdDlg : public QDialog { Q_OBJECT public: MatlabCmdDlg(QWidget *parent = Q_NULLPTR); ~MatlabCmdDlg(); void openMatlabEngine();//打开Matlab Engine //.... private: void closeMatlabEngine();//关闭Matlab Engine //.... private: //.... Engine* m_ep = NULL; //定义Matlab engine类型指针,往后函数都要用它来指示目标 threadMatlab* m_pThreadMatlab;//用于打开Matlab Engine private slots: void slot_openMatlabEngine(bool isOpenMatlabEngine); //.... };
#include "MatlabCmdDlg.h" #include <QMessageBox> //... MatlabCmdDlg::~MatlabCmdDlg() { closeMatlabEngine(); if (nullptr != m_pThreadMatlab) { disconnect(m_pThreadMatlab, SIGNAL(openMatlabEngine(bool)), this, SLOT(slot_openMatlabEngine(bool))); m_pThreadMatlab->quitThead();//退出机制 m_pThreadMatlab->quit(); m_pThreadMatlab->wait(); delete m_pThreadMatlab; } } void MatlabCmdDlg::openMatlabEngine() { if (nullptr!=m_pThreadMatlab) {//线程已经打开 return; } //创建线程 m_pThreadMatlab = new threadMatlab(this); // 将Matlab Engine的指针的指针赋值给线程中的变量,让线程去创建Matlab Engine指针 m_pThreadMatlab->setMatlabEngine(&m_ep); // connect函数,最后一个参数需要注意,不能使用默认 connect(m_pThreadMatlab, SIGNAL(openMatlabEngine(bool)), this, SLOT(slot_openMatlabEngine(bool)), Qt::QueuedConnection); ui.lab_central->setText("Matlab Engine 正在启动,请稍后..."); m_pThreadMatlab->start();//启动线程就会打开Matlab Engine } void MatlabCmdDlg::closeMatlabEngine() { //... } void MatlabCmdDlg::moveMatlabCmdIntoDlg() {//将Matlab Engine的窗口 嵌入到本窗口中 //... } void MatlabCmdDlg::slot_openMatlabEngine(bool isOpenMatlabEngine) {//当Matlab 启动后发送消息,主线程接收到消息进行处理 if (isOpenMatlabEngine) {//Matlab Engine已经打开 ui.lab_central->setText("Matlab Engine 打开成功!"); moveMatlabCmdIntoDlg();//嵌入Matlab Cmd 到本Dlg } else {//Matlab Engine打开失败 ui.lab_central->setText("Matlab Engine 打开失败!"); } } //...
自定义信号用关键词signals:
,类似C++
的关键词public、private
等用法一致。
如果要自定义保护信号,就在protected:
后声明。
自定义信号只需要在头文件的类声明中声明, 然后将槽
连接到信号
即可,无需实现信号函数。
信号函数与槽函数的返回值类型
在任何时候都可以不同,而且如果不关心信号传递下来的参数,信号函数与槽函数的参数列表也可以不相同
, 但是如果要访问信号传递下来的任何参数时, 信号函数 与 槽函数 的参数列表必须相同
。
发送信号
只需要用关键字emit
后面加上要发的信号,如果要信号函数是有参数
的,可以通过形参
给槽函数传值。
emit openMatlabEngine(m_isOpenMatlabEngine);
emit openMatlabEngine(true);
emit openMatlabEngine(false);
// connect函数,最后一个参数需要注意,不能使用默认
connect(m_pThreadMatlab, SIGNAL(openMatlabEngine(bool)), this, SLOT(slot_openMatlabEngine(bool)), Qt::QueuedConnection);
这个参数可以用于线程间的信号传递,详细信息见博文:[Qt]connect()参数Qt:ConnectionType使用讲解
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。