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

跨UI发送信号

基本框架

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

新建窗口

在这里插入图片描述

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

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

自定义信号

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

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

跨线程发送信号

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

在这里插入图片描述

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

新建线程

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

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

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

查看线程号

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

完整代码

跨UI发送信号

setdialog.h

#ifndef SETDIALOG_H
#define SETDIALOG_H

#include <QDialog>

namespace Ui {
class setdialog;
}

class setdialog : public QDialog
{
    Q_OBJECT

public:
    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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    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_OBJECT

public:
    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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    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。

结尾

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/735929.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python】已解决:ModuleNotFoundError: No module named ‘paddle’

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;ModuleNotFoundError: No module named ‘paddle’ 一、分析问题背景 在Python编程中&#xff0c;ModuleNotFoundError是一个常见的错误&#xff0c;它通常发生…

C语言的数据结构:树与二叉树(树篇)

前言 之前所学到的数据结构都是线性结构特征&#xff0c;所谓线性就是在结构上&#xff0c;将节点连接起来时&#xff0c;像一条线一样。如链表则是上一个节点包含下一个节点地址的指针&#xff0c;这样依次下去。而串、队列、栈则实现方式都依赖于链表或顺序表而实现&#xf…

Inception_V2_V3

Inception_V2_V3 CNN卷积网络的发展史 1. LetNet5(1998) 2. AlexNet(2012) 3. ZFNet(2013) 4. VGGNet(2014) 5. GoogLeNet(2014) 6. ResNet(2015) 7. DenseNet(2017) 8. EfficientNet(2019) 9. Vision Transformers(2020) 10. 自适应卷积网络(2021) 上面列出了发展到现在CNN的…

智能优化算法改进策略之局部搜索算子(三)—二次插值法

1、原理介绍 多项式是逼近函数的一种常用工具。在寻求函数极小点的区间&#xff08;即寻查区间&#xff09;上&#xff0c;我们可以利用在若干点处的函数值来构成低次插值多项式&#xff0c;用它作为求极小点的函数的近似表达式&#xff0c;并用这个多项式的极小点作为原函数极…

示例:推荐一个基于第三方开源控件库DataGridFilter封装的FilterColumnDataGrid,可以像Excel拥有列头筛选器

一、目的&#xff1a;基于第三方开源控件库DataGridFilter封装的FilterColumnDataGrid&#xff0c;可以像Excel拥有列头筛选器&#xff0c;感兴趣的可以去下方链接地址查看开源控件库地址。本控件封装的目的在于将第三方库的皮肤和样式封装到皮肤库中可统一设置样式&#xff0c…

Day 31:100334. 包含所有1的最小矩形面积Ⅰ

Leetcode 100334. 包含所有1的最小矩形面积Ⅰ 给你一个二维 **二进制 **数组 grid。请你找出一个边在水平方向和竖直方向上、面积 最小 的矩形&#xff0c;并且满足 grid 中所有的 1 都在矩形的内部。 返回这个矩形可能的 **最小 **面积。 确定首次出现 1 的第一行 top&#xf…

转让神州开头的无区域科技公司需要多少钱

您好&#xff0c;我公司现有2家无区域神州名称的公司转让。所谓无区域名称是公司名称中不带有行政区划、及行业特点的公司名称&#xff0c;都是需要在工商总,局核准名称的&#xff0c;对于民营企业来说也比较喜欢这种名称名称很大气&#xff0c;现在重核更严格了&#xff0c;所…

报错:mAP数据为0%+无法读取output里的图片红色警告

debug检查&#xff1a;发现创建的output和input的路径不在同一级 操作1&#xff1a;修改output创建路径为绝对路径后&#xff0c;output和input文件成功在同一级&#xff0c;但问题仍存在 debug检测&#xff1a;识别的类别和保存的类别不同&#xff0c;没有保存数据 操作2&…

WMS项目测试点

这里写目录标题 最后附有图片 仓库系统 仓库 / 库区 仓库 新增仓库 编号 必填校验 字段长度校验 20为字符 数据类型校验 名称 必填校验 字段长度校验 20为字符 数据类型校验 备注 填写备注校验 字符长度限制 不填写备注校验 新增仓库之后是否可以通过查询仓库名称和仓库编号查询…

linux系统cpu飙高如何排查

1.通过top命令查看cpu占比较高的进程ID 2.通过top -H -p <进程ID>命令查看该进程中具体线程&#xff0c;可以看到第一个线程 4311 占用了88.2%的cpu 3.通过 printf "%x\n" <线程ID> 把10进制的线程id转为16进制 4.通过jstack <进程ID> | grep &…

体检项目里的中文名称和英文简称

在做驾驶员体检、健康证等体检时&#xff0c;会看到不同的体检项目名称&#xff0c;比如有身高、体重、眼睛视力、耳鼻喉、肝功能、心电图等。     在体检之前的一周&#xff0c;要注意休息好、清淡饮食。晚上10点之前入睡&#xff0c;不要熬夜。贝壳类食物&#xff0c;比如花…

本地离线模型搭建指南-RAG架构实现

搭建一个本地中文大语言模型&#xff08;LLM&#xff09;涉及多个关键步骤&#xff0c;从选择模型底座&#xff0c;到运行机器和框架&#xff0c;再到具体的架构实现和训练方式。以下是一个详细的指南&#xff0c;帮助你从零开始构建和运行一个中文大语言模型。 本地离线模型搭…

云手机在跨平台兼容性方面优势明显?有何应用场景

跨平台设备间无缝切换和数据同步的需求现在是很多人或者企业都需要的&#xff0c;云手机在这些方面似乎有很大优势&#xff1f;下面我们来具体探讨在兼容方面&#xff0c;云手机有何出彩之处&#xff1f;又支持哪些应用场景呢 先来说说云手机跨平台兼容性优势所在&#xff0c;要…

动态规划——活动安排问题II(C++)

Take it easy! 2024年6月19日 题目描述 假设有n个活动和一个资源&#xff0c;每个活动执行时都需要占用该资源&#xff0c;并且该资源在任何时间只能被一个活动所占用&#xff0c;一旦某个活动开始执行&#xff0c;中间将不能被打断&#xff0c;直到其执行完毕。每个活动i都有…

WordPress主题仿虎嗅网/雷锋网自媒体主题(两套打包)

主题介绍 这两款wordpress主题是精仿虎嗅网和雷锋网的&#xff0c;这两款主题应该是没有多大BUG&#xff0c;同时这两款主题目前跟现在的虎嗅、雷锋两个网站看上去并没有多大区别&#xff0c;唯一美中不足的就是不支持PHP7.0以上。经常逛虎嗅网与雷锋网的同志应该是喜欢这两款…

Spring框架的核心原则和IoC容器介绍

Spring框架是一个开源的应用程序框架&#xff0c;它遵循以下核心原则&#xff1a; 1.Inversion of Control&#xff08;控制反转&#xff09;: Spring框架通过IoC容器管理对象的生命周期和依赖关系&#xff0c;而不是由程序代码直接创建对象。这样可以降低组件之间的耦合度&…

阅读笔记:明朝那些事儿妖孽横行的宫廷

明朝那些事儿第四部看完了&#xff0c;合上书本给我印象比较深刻的文臣要数王守仁&#xff0c;不愧为明朝的军事家&#xff0c;思想家&#xff0c;文学家&#xff0c;教育家&#xff0c;他经过多年的思索、磨难、追求&#xff0c;终于有一天&#xff0c;在穷乡僻壤&#xff0c;…

UEC++ 虚幻5第三人称射击游戏(一)

UEC 虚幻5第三人称射击游戏&#xff08;一&#xff09; 创建一个空白的C工程 人物角色基本移动 创建一个Character类添加一些虚幻商城中的基础动画 给角色类添加Camera与SPringArm组件 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category "SpringArm")clas…

设计软件有哪些?贴图插件篇(1),渲染100邀请码1a12

设计师经常要处理贴图&#xff0c;这里介绍一些贴图所用到的插件。 1、Substance 3D Painter Substance 3D Painter是Substance 3D软件套件中的一部分&#xff0c;是一款专业的纹理绘制软件。它提供了直观的界面和强大的工具&#xff0c;用于在3D模型上进行高质量的纹理绘制和…

Docker常用命令与实战示例

docker 1. 安装2. 常用命令3. 存储4. 网络5. redis主从复制示例6. wordpress示例7. DockerFile8. 一键安装超多中间件&#xff08;compose&#xff09; 1. 安装 以centOS系统为例 # 移除旧版本docker sudo yum remove docker \docker-client \docker-client-latest \docker-c…