精华内容
下载资源
问答
  • [Qt]自定义信号signals和emit信号

    万次阅读 多人点赞 2019-01-08 13:35:24
    原创文章,欢迎转载。转载请注明:转载自 祥的博客 原文链接: 文章目录@[toc]1.问题来源2.代码2.1. 子线程代码头文件 threadMatlab.h源文件 ...Qt自定义信号signals和emit信号 1.问题来源 Qt调用Matlab...


    原创文章,欢迎转载。转载请注明:转载自 祥的博客

    原文链接:https://blog.csdn.net/humanking7/article/details/86071134


    Qt自定义信号signals和emit信号

    1.问题来源

    Qt调用Matlab Engine,但是Matlab Engine打开太慢了,如果放在UI主线程中会造成界面卡死,所以打算开一个线程去打开Matlab Engine,当其打开后,向UI主线程发送signal消息,当UI主线程slot槽接收到消息后,就会将Matlab Engine对应的Matlab Command Window对话框嵌入到UI主线程的界面中。

    所以本文的所需解决的问题就是:

    在一个线程中发送一个自定义signal信号,另一线程的slot槽接收到消息后,进行相应

    2.代码

    2.1. 子线程代码

    头文件 threadMatlab.h

    #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;//是否要退出
    };
    

    源文件 threadMatlab.cpp

    #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); 
    			}
    		}
    	}
    
    }
    

    2.2. 主线程代码

    头文件

    #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 打开失败!");
    	}
    }
    
    //...
    
    
    

    3. 讲解

    3.1. 整体程序信号流程

    流程

    3.2. 信号说明

    自定义信号用关键词signals:,类似C++的关键词public、private等用法一致。
    如果要自定义保护信号,就在protected:后声明。
    自定义信号只需要在头文件的类声明中声明, 然后将连接到信号即可,无需实现信号函数
    信号函数槽函数返回值类型任何时候都可以不同,而且如果不关心信号传递下来的参数,信号函数槽函数参数列表也可以不相同, 但是如果要访问信号传递下来的任何参数时, 信号函数槽函数参数列表必须相同

    发送信号
    只需要用关键字emit后面加上要发的信号,如果要信号函数是有参数的,可以通过形参槽函数传值。

    emit openMatlabEngine(m_isOpenMatlabEngine); 
    emit openMatlabEngine(true);
    emit openMatlabEngine(false); 
    

    3.3. connect说明

    // connect函数,最后一个参数需要注意,不能使用默认
    connect(m_pThreadMatlab, SIGNAL(openMatlabEngine(bool)), this, SLOT(slot_openMatlabEngine(bool)), Qt::QueuedConnection);
    

    这个参数可以用于线程间的信号传递,详细信息见博文:[Qt]connect()参数Qt:ConnectionType使用讲解


    赞赏码New

    展开全文
  • qt不同线程emit信号需要使用qMetaType

    千次阅读 2017-11-05 20:59:45
    在使用中遇到了”emit信号,但是ui线程并没有收到”的问题,经过排查发现如果信号函数没有参数ui县城可以接收,但是有参数就不能接收。 原因是在qt中这样的局部变量需要通过”注册元数据”的形式先注册才可以使用...

    在使用中遇到了”emit信号,但是ui线程并没有收到”的问题,经过排查发现如果信号函数没有参数ui县城可以接收,但是有参数就不能接收。
    原因是在qt中这样的局部变量需要通过”注册元数据”的形式先注册才可以使用

    解决方案:

    在main函数中写
    qRegisterMetaType<"类型">( "类型" );
    如类型是string,那么写
    qRegisterMetaType<std::string>("std::string");

    头文件是 QMetaType

    展开全文
  • 今天遇到个坑,往主界面往模式对话框emit信号。应为模式对话框exec后,主界面就不响应了,emit也发不了。所以要先emit,再exec。运行截图如下:正常情况下:此时,相关代码如下:void Widget::openBtnClicked(){ m_...

    今天遇到个坑,往主界面往模式对话框emit信号。

    应为模式对话框exec后,主界面就不响应了,emit也发不了。所以要先emit,再exec。


    运行截图如下:

    正常情况下:


    此时,相关代码如下:

    void Widget::openBtnClicked(){
        m_dialog=new Dialog();
        connect(this,SIGNAL(btnClicked(QString)),m_dialog,SLOT(receive(QString)));
        emit btnClicked(ui->lineEdit->text());
        m_dialog->exec();
    }


    不正常情况下:


    代码如下:

    void Widget::openBtnClicked(){
        m_dialog=new Dialog();
        connect(this,SIGNAL(btnClicked(QString)),m_dialog,SLOT(receive(QString)));
        m_dialog->exec();
        emit btnClicked(ui->lineEdit->text());
    }




    --------------------------------------------------------------------------------------

    下面给出正常情况下的代码:

    dialog.h

    #ifndef DIALOG_H
    #define DIALOG_H
    
    #include <QDialog>
    
    namespace Ui {
    class Dialog;
    }
    
    class Dialog : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit Dialog(QWidget *parent = 0);
        ~Dialog();
    public slots:
        void receive(QString msg);
    
    private:
        Ui::Dialog *ui;
    };
    
    #endif // DIALOG_H

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include "dialog.h"
    
    
    namespace Ui {
    class Widget;
    }
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Widget(QWidget *parent = 0);
        ~Widget();
    
    public slots:
        void openBtnClicked();
    
    signals:
        void btnClicked(QString msg);
    
    private:
        Ui::Widget *ui;
        Dialog *m_dialog;
    
    };
    
    #endif // WIDGET_H
    

    dialog.cpp

    #include "dialog.h"
    #include "ui_dialog.h"
    
    Dialog::Dialog(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::Dialog)
    {
        ui->setupUi(this);
    }
    
    void Dialog::receive(QString msg){
        ui->lineEdit->setText(msg);
    }
    
    Dialog::~Dialog()
    {
        delete ui;
    }

    widget.cpp

    #include "widget.h"
    #include "ui_widget.h"
    
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(openBtnClicked()));
    }
    
    void Widget::openBtnClicked(){
        m_dialog=new Dialog();
        connect(this,SIGNAL(btnClicked(QString)),m_dialog,SLOT(receive(QString)));
        emit btnClicked(ui->lineEdit->text());
        m_dialog->exec();
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    

    main.cpp

    #include "widget.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
    
        return a.exec();
    }
    


    展开全文
  • Qt提升基础类emit信号

    2020-04-07 18:57:02
    Qt在A类主界面提升widget为该B 类 ,提升之后设置接收emit信号 #include "qttest.h" QtTest::QtTest(QWidget *parent) : QWidget(parent) { ui.setupUi(this); QFont sansFont("Helvetica [Cronyx]", 12); ui....

    类A为界面基础类:

    #include <QtWidgets/QWidget>
    #include "ui_qttest.h"
    #include "qaddclass.h"
    class QtTest : public QWidget
    {
    	Q_OBJECT
    
    public:
    	QtTest(QWidget *parent = 0);
    	~QtTest();
    public slots:
    	void doslots();
    	//接收B类信号槽函数
    	void getstr(QString str);
    private:
    	Ui::QtTestClass ui;
    public:
    	QAddClass *myclass;
    };
    

    类B为界面提升类:

    class QAddClass : public QWidget
    {
    	Q_OBJECT
    
    public:
    	QAddClass(QWidget *parent = 0);
    	~QAddClass();
    signals:
    	//信号发出函数
    	void StrSigs(QString str);
    public slots:
    	void pussButtonDown();
    };
    

    Qt在A类主界面提升widget为该B 类 ,提升之后设置接收emit信号

    #include "qttest.h"
    
    QtTest::QtTest(QWidget *parent)
    	: QWidget(parent)
    {
    	ui.setupUi(this);
    	QFont sansFont("Helvetica [Cronyx]", 12);
    	ui.lineEdit->setFont(sansFont);
    	connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(doslots()));
    	//界面提升类///
    	connect(ui.widget, SIGNAL(StrSigs(QString)), this, SLOT(getstr(QString)));
    }
    
    QtTest::~QtTest()
    {
    
    }
    
    void QtTest::doslots()
    {
    	QString str = ui.lineEdit->text();
    
    	ui.pushButton->setText(str);
    }
    
    void QtTest::getstr(QString str)
    {
    	ui.lineEdit->setText(str);
    }
    
    展开全文
  • emit信号发送结构体

    千次阅读 2014-09-09 16:03:41
     emit rcvComData(var1);  ///time1.stop();  }  [html]   view plain copy #include "ctestdefinesignal.h"  #include  < QDebug >     ...
  • 我做了个最简单的程序托盘...我做了个exitsignal_2()信号,moc文件里同样会生成类似上面的代码,但是activate的第三个参数变为1了,emit这个信号的时候无法关闭程序 很想搞明白是什么使这样的情况出现,谢谢各位了!
  • 参见:E:\svnroot\20190408...sp线程发送信号到界面主线程。 Qt::BlockingQueuedConnection https://blog.csdn.net/luotuo44/article/details/39395025 转载于:https://www.cnblogs.com/damoying/p/10819757.html
  • 新手求大佬帮助呀,重写了mouseReleaseEvent和keyReleaseEvent,调试都能执行emit customRightClicked();这句,然后就没反应了,程序执行不到对应的槽函数 头文件 #pragma once #include"global.h"//包含了...
  • 上图中第24秒934毫秒为子线程结束的时间,第24秒923毫秒为子线程中使用emit发送信号的时间,第30秒025毫秒为信号槽接收到数据准备处理的时间,可以看到子线程发送信号到主线程接收到开始处理数据中间大概间隔了5秒...
  • 在写UDP接收程序时,接收是一个单独的子线程,然后当接收到的数据达到一定的量后,发送到另一个子线程中...其实不止这一个信号,UI线程当我发送清零信号到子线程中去也是这个错误,所以请问下各位该怎么解决这种问题。
  • 子线程向主线程emit信号,主线程的这个相应的槽函数是否要加锁?
  • 以引用作为参数一定要注意,在第二次发射信号的时候,引用的实体已经不存在了。 所以,如果想让每一次发射的信号中参数的值都保存下来,不能是&引用和*指针作为参数,而应该使用值传递。 这样每次发射信号...
  • 触发非定义信号(按钮) emit ui.btn->clicked(); 即可触发btn按钮的点击槽函数
  • 再Qt使用过程中,可以自定义信号,但是有时候,开发者并不确定这个信号是否被连接,而是直接发送,这样会导致资源得浪费。如果再信号发送之前加上判断,如果连接上了,再发送该信号,具体操作如下: 使用这个...
  • emit是为了调用对应的槽函数,用来发射信号
  • 如果使用自定义信号,一定要记得信号是类变量,必须在类中定义,不能在实例方法中定义,否则后面发射信号和连接槽方法时都会报错。 案例: class configWin(ui_configWin.Ui_configWin,QtWidgets.QWidget): ...
  • 一、自定义信号 关键字:signals signals : void ageChanged(int age); //虽然是一个函数,但是无需实现,参数age会传递到槽函数 二、信号和槽函数的关联 ...connect(boy,&...关键字:emit ...
  • 简介: 讲解Qt的emit发射(信号)、signals信号、slot槽的使用 文章目录本博文的简述or解决问题?重要提示:信号槽元对象工具程序样例**应注意的问题**参考博文:本篇同步博文: 本博文的简述or解决问题? ​ 讲解...
  • 现在的问题是,在tcp的类中emit时会报出信号函数是无法解析的外部符号,在UI 类中已经实现了connect,信号与槽都是一个类型的参数,信号只声明没定义,槽已定义好。。。找了半天仍没有找到原因。大家帮帮我吧,,...
  • 初学者,想实现在子窗口中,点击close的按键,signal类emit 出 mysignal()信号,打印“emit success”,然后Widget::kong的槽函数接收到,打印“slot kong accept success”。 但是目前的情况是,Widget::...
  • 1.相关概念: [1].信号(Signal)就是在特定情况下被发射的事件 [2].槽(Slot)就是对信号...//信号发出者,处理的信号信号接收者,处理动作方法(槽函数)。 注解: [1].sender 是发射信号的对象的名称,[2]

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 586
精华内容 234
关键字:

emit信号