【七】【QT开发应用】跨UI发送信号,跨线程发送信号

2024-06-23 19:20

本文主要是介绍【七】【QT开发应用】跨UI发送信号,跨线程发送信号,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

跨UI发送信号

基本框架

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

新建窗口

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

自定义信号

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

跨线程发送信号

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

新建线程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

查看线程号

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完整代码

跨UI发送信号

setdialog.h

#ifndef SETDIALOG_H
#define SETDIALOG_H#include <QDialog>namespace Ui {
class setdialog;
}class setdialog : public QDialog
{Q_OBJECTpublic:explicit setdialog(QWidget *parent = nullptr);~setdialog();private slots:void on_btnAdd_clicked();signals:void sig_addOne(int value);private:Ui::setdialog *ui;
};#endif // SETDIALOG_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_btnOpen_clicked();private:Ui::Widget *ui;
};
#endif // WIDGET_H

setdialog.cpp

#include "setdialog.h"
#include "ui_setdialog.h"setdialog::setdialog(QWidget *parent): QDialog(parent), ui(new Ui::setdialog)
{ui->setupUi(this);
}setdialog::~setdialog()
{delete ui;
}void setdialog::on_btnAdd_clicked(){static int score=100;emit sig_addOne(score++);}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <setdialog.h>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::on_btnOpen_clicked(){setdialog dlg;connect(&dlg ,&setdialog::sig_addOne,[=](int value){ui->lineEdit_score->setText(QString::number(value));});dlg.exec();
}

跨线程发送信号

childthread.h

#ifndef CHILDTHREAD_H
#define CHILDTHREAD_H#include <QThread>using namespace std;
#include <string>struct Score{string name;int id;int age;
};class ChildThread : public QThread
{Q_OBJECTpublic:ChildThread();signals:void sig_SendToUI(Score score);protected:void run() override;};#endif // CHILDTHREAD_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <childthread.h>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_btnUpdate_clicked();void showInfo(Score s);private:Ui::Widget *ui;
};
#endif // WIDGET_H

childthread.cpp

#include "childthread.h"
#include <QDebug>ChildThread::ChildThread() {}void ChildThread::run(){Score s;s.name="Jack";s.age=18;s.id=10086;emit sig_SendToUI(s);qDebug()<<"ui thread id4_run = "<<QThread:: currentThreadId();}

widget.cpp


#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <childthread.h>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}
void Widget::on_btnUpdate_clicked(){qDebug()<<"正常运行";ChildThread* ch=new ChildThread;connect(ch,&ChildThread::sig_SendToUI,this,&Widget::showInfo);ch->start();qDebug()<<"ui thread id2_btnUpdate = "<<QThread:: currentThreadId();
}void Widget::showInfo(Score s){string info="name="+s.name+" id="+to_string(s.id)+" age="+to_string(s.age);ui->lineEdit->setText(QString::fromStdString(info));qDebug()<<"ui thread id3_showInfo = "<<QThread:: currentThreadId();
}

复盘

跨UI发送信号

跨UI发送信号是指在不同用户界面组件之间传递信息,以实现交互和数据共享。

Qt的信号和槽机制是跨UI组件通信的经典方法。信号和槽允许对象之间进行松耦合的通信:
信号:由对象发出,表示某个事件发生。
槽:可以是任何可调用对象,当信号发出时,槽会被调用。
连接:通过QObject::connect方法将信号和槽连接起来。

void Widget::on_btnOpen_clicked(){setdialog dlg;connect(&dlg ,&setdialog::sig_addOne,[=](int value){ui->lineEdit_score->setText(QString::number(value));});dlg.exec();
}
  1. void Widget::on_btnOpen_clicked()

这是一个槽函数,用于响应名为 btnOpen 的按钮点击事件。Widget 是一个自定义的类,包含这个槽函数。

  1. setdialog dlg;

这里创建了一个 setdialog 类型的对象 dlg。

  1. connect(&dlg, &setdialog::sig_addOne, [=](int value){ ui->lineEdit_score->setText(QString::number(value)); });

这行代码使用了 Qt 的信号和槽机制,建立了一个连接:
&dlg 是信号发送者,即 setdialog 对象。
&setdialog::sig_addOne 是 setdialog 类中的一个信号。
[=](int value){ … } 是一个Lambda表达式,作为槽函数。当信号 sig_addOne 发出时,这个Lambda函数会被调用,接收一个整数参数 value。
ui->lineEdit_score->setText(QString::number(value)); 将接收到的 value 转换为字符串,并设置到 lineEdit_score 控件中显示。

  1. dlg.exec();

这行代码以模态方式运行对话框 dlg。exec() 函数会阻塞,直到对话框关闭。
执行事件循环.

void setdialog::on_btnAdd_clicked(){static int score=100;emit sig_addOne(score++);
}

代码解析

  1. void setdialog::on_btnAdd_clicked()

这是一个槽函数,用于响应 setdialog 类中名为 btnAdd 的按钮点击事件。

  1. static int score = 100;

声明并初始化一个静态局部变量 score,初始值为 100。
静态局部变量在函数调用之间保持其值不变。也就是说,每次调用这个函数时,score 的值都会在上一次调用的基础上增加,而不会每次重新初始化为 100。

  1. emit sig_addOne(score++);

emit 关键字用于发出信号。这里发出的是 sig_addOne 信号。
score++ 是后置递增运算符,意味着在发出信号时,score 的当前值将被使用,然后 score 自增 1。
例如,第一次点击按钮时,score 的值是 100,信号 sig_addOne 发出时传递的值是 100,然后 score 增加到 101。
下一次点击按钮时,score 的值是 101,信号 sig_addOne 发出时传递的值是 101,然后 score 增加到 102。

信号和槽的工作流程

当用户点击 btnAdd 按钮时,on_btnAdd_clicked() 函数会被调用。
该函数发出 sig_addOne 信号,并传递当前的 score 值。
score 值会在每次按钮点击后递增,因此每次发出的信号都会传递一个增加后的 score 值。
在主窗口的槽函数中(如之前提到的 on_btnOpen_clicked()),连接到 sig_addOne 信号的槽函数会接收到这个 score 值,并在界面上更新显示。

跨线程发送信号

void ChildThread::run(){Score s;s.name="Jack";s.age=18;s.id=10086;emit sig_SendToUI(s);qDebug()<<"ui thread id4_run = "<<QThread:: currentThreadId();}
  1. void ChildThread::run()

这是 ChildThread 类的 run 方法,是线程的入口点。在 QThread 中,run 方法会在调用 start 后在子线程中执行。

  1. Score s;

创建一个 Score 类型的对象 s。Score 可能是一个自定义的数据结构或类。

  1. s.name=“Jack”;

设置 Score 对象 s 的 name 属性为 “Jack”。

  1. s.age=18;

设置 Score 对象 s 的 age 属性为 18。

  1. s.id=10086;

设置 Score 对象 s 的 id 属性为 10086。

  1. emit sig_SendToUI(s);

发出信号 sig_SendToUI,并传递 Score 对象 s。
sig_SendToUI 是 ChildThread 类中的一个自定义信号,用于将数据传递到主线程的UI组件中进行显示或处理。

  1. qDebug()<<"ui thread id4_run = "<<QThread:: currentThreadId();

输出当前线程的线程ID,使用 qDebug() 进行调试打印。
QThread::currentThreadId() 返回当前线程的ID,可以用来验证代码是在子线程中执行的。

通过这种方式,子线程可以安全地将数据传递到主线程,并在UI中进行显示或处理。

void Widget::on_btnUpdate_clicked(){qDebug()<<"正常运行";ChildThread* ch=new ChildThread;connect(ch, &ChildThread::sig_SendToUI, this, &Widget::showInfo);ch->start();qDebug()<<"ui thread id2_btnUpdate = "<<QThread::currentThreadId();
}
  1. void Widget::on_btnUpdate_clicked()

这是一个槽函数,用于响应 btnUpdate 按钮的点击事件。

  1. qDebug()<<“正常运行”;

使用 qDebug() 输出调试信息,表示槽函数已被正确调用。

  1. ChildThread* ch = new ChildThread

动态创建一个 ChildThread 对象 ch。ChildThread 类继承自 QThread,它代表一个独立的执行线程。

  1. connect(ch, &ChildThread::sig_SendToUI, this, &Widget::showInfo);

使用 Qt 的信号和槽机制,将子线程 ch 的 sig_SendToUI 信号连接到当前对象(Widget 类实例)的 showInfo 槽函数。
sig_SendToUI 是 ChildThread 类中定义的一个信号。
showInfo 是 Widget 类中的一个槽函数,用于处理来自子线程的数据并更新UI。

  1. ch->start();

调用 ch 的 start() 方法启动子线程。start() 方法会调用 ChildThread 类中的 run() 方法,在子线程中执行其中的代码。

  1. qDebug()<<"ui thread id2_btnUpdate = "<<QThread::currentThreadId();

使用 qDebug() 输出当前线程的线程ID,帮助开发者确认代码在主线程中执行。

**创建并启动子线程:**当用户点击 btnUpdate 按钮时,程序会动态创建一个 ChildThread 对象并启动子线程。
**连接信号和槽:**将子线程的信号 sig_SendToUI 连接到主线程的槽函数 showInfo。这样,当子线程发出信号时,主线程的槽函数会被调用,以更新UI。
**调试输出:**输出调试信息,确认槽函数被调用和线程ID。

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!

这篇关于【七】【QT开发应用】跨UI发送信号,跨线程发送信号的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1088049

相关文章

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

亮相WOT全球技术创新大会,揭秘火山引擎边缘容器技术在泛CDN场景的应用与实践

2024年6月21日-22日,51CTO“WOT全球技术创新大会2024”在北京举办。火山引擎边缘计算架构师李志明受邀参与,以“边缘容器技术在泛CDN场景的应用和实践”为主题,与多位行业资深专家,共同探讨泛CDN行业技术架构以及云原生与边缘计算的发展和展望。 火山引擎边缘计算架构师李志明表示:为更好地解决传统泛CDN类业务运行中的问题,火山引擎边缘容器团队参考行业做法,结合实践经验,打造火山

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用。如果你看不懂,请留言。 完整代码: <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><ti

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa

气象站的种类和应用范围可以根据不同的分类标准进行详细的划分和描述

气象站的种类和应用范围可以根据不同的分类标准进行详细的划分和描述。以下是从不同角度对气象站的种类和应用范围的介绍: 一、气象站的种类 根据用途和安装环境分类: 农业气象站:专为农业生产服务,监测土壤温度、湿度等参数,为农业生产提供科学依据。交通气象站:用于公路、铁路、机场等交通场所的气象监测,提供实时气象数据以支持交通运营和调度。林业气象站:监测林区风速、湿度、温度等气象要素,为林区保护和

DDS信号的发生器(验证篇)——FPGA学习笔记8

前言:第一部分详细讲解DDS核心框图,还请读者深入阅读第一部分,以便理解DDS核心思想 三刷小梅哥视频总结! 小梅哥https://www.corecourse.com/lander 一、DDS简介         DDS(Direct Digital Synthesizer)即数字合成器,是一种新型的频率合成技术,具有低成本、低功耗、高分辨率、频率转换时间短、相位连续性好等优点,对数字信

[FPGA][基础模块]跨时钟域传播脉冲信号

clk_a 周期为10ns clk_b 周期为34ns 代码: module pulse(input clk_a,input clk_b,input signal_a,output reg signal_b);reg [4:0] signal_a_widen_maker = 0;reg signal_a_widen;always @(posedge clk_a)if(signal_a)

将一维机械振动信号构造为训练集和测试集(Python)

从如下链接中下载轴承数据集。 https://www.sciencedirect.com/science/article/pii/S2352340918314124 import numpy as npimport scipy.io as sioimport matplotlib.pyplot as pltimport statistics as statsimport pandas

WDF驱动开发-WDF总线枚举(一)

支持在总线驱动程序中进行 PnP 和电源管理 某些设备永久插入系统,而其他设备可以在系统运行时插入和拔出电源。 总线驱动 必须识别并报告连接到其总线的设备,并且他们必须发现并报告系统中设备的到达和离开情况。 总线驱动程序标识和报告的设备称为总线的 子设备。 标识和报告子设备的过程称为 总线枚举。 在总线枚举期间,总线驱动程序会为其子 设备创建设备对象 。  总线驱动程序本质上是同时处理总线枚