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

news2025/1/16 13:53:20

跨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。

结尾

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT实现QGraphicsView绘图 重写QGraphicsSvgItem类实现边框动画

目录导读 简述使用 QTimer 实现 QGraphicsSvgItem 边框动画效果 简述 在了解学习WPS的流程图的时候&#xff0c;发现它这个选择图元有个动态边框效果&#xff0c;而且连接线还会根据线生成点从头移动到尾的动画。像这种&#xff1a; 在QML中实现这种动画属性很简单&#xff0…

物联网系统运维——移动电商服务器单点部署,web服务器部署,Nginx Web服务介绍,Nginx性能,部署,架构,及实验:安装并设置Nginx(重点)

一.web服务器介绍 Web服务器一般指网站服务器&#xff0c;是指驻留于因特网上提供某种特定类型计算机的程序&#xff0c;Web服务器可以向浏览器等Web客户端提供文档&#xff0c;也可以放置网站文件&#xff0c;让全世界浏览&#xff0c;可以放置数据文件&#xff0c;让全世界下…

七种常见的前端攻击

随着网络应用程序在商业运作中的重要性日益增加&#xff0c;它们也成为了网络攻击的更具吸引力的目标。不幸的是&#xff0c;与后端和 DevOps 团队相比&#xff0c;许多前端开发人员在构建安全前端方面已经落后了。这种差距增加了破坏性数据泄露的风险。 最近的事件&#xff0…

Linux_软硬链接

目录 1、软链接 2、软链接的使用方式 3、软链接的删除 4、硬链接 5、硬链接的使用方式 6、软硬链接的使用场景 7、软硬链接的区别 结语 前言&#xff1a; 在Linux操作系统中&#xff0c;有软链接和硬链接&#xff0c;他们是一种特殊的文件引用&#xff0c;主要用于与…

AGV机器人的调度开发分析(1)- 内核中的路线规划

准备开始写一个系列&#xff0c;介绍下AGV机器人的调度的开发和应用。 按照openTCS的核心内容&#xff0c;国内多家广泛应用于AGV的调度。那么架构图如下&#xff1a; Kernel中有一个是Routing&#xff0c;这是路由规划模块&#xff0c;需要实现的细节功能包括如下&#xff1a…

理解什么是DSR,嗅探器视角下的IP和MAC地址识别(C/C++代码实现)

网络嗅探器是监控和分析网络流量的一种工具&#xff0c;它能够捕获数据包并提取出关键的信息&#xff0c;比如IP地址和MAC地址。 网络嗅探器工作原理基于网卡的工作模式。正常情况下&#xff0c;网卡只处理发送给它的数据包&#xff0c;忽略其他数据。但是&#xff0c;如果将网…

Java程序之简单“记事本”

要求&#xff1a;如下图所示&#xff0c;记事本具有新建、打开文本、保存、关闭等功能。 算法思路&#xff1a; 这是一个使用Java Swing库创建的简单文本编辑器。它包含一个菜单栏&#xff0c;其中包含“文件”菜单以及四个子菜单项&#xff1a;“新建”、“打开”、“保存”和…

机器学习课程复习——集成学习

1. 基本概念 1.1. 定义 通过构建并结合多个个体学习器来完成学习任务,获得比单一学习器显著优越的泛化性能。 1.2. 分类 名称个体学习器例子同质集成基学习器Boosting、Bagging异质集成组件学习器Stacking1.3. 研究的核心 个体学习器的“准确性”和“多样性”本身就存在冲…

二叉树经典OJ练习

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 二叉树经典OJ练习 收录于专栏【数据结构初阶】 本专栏旨在分享学习数据结构学习的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 前置说…

三、MyBatis实践:提高持久层数据处理效率

三、MyBatis实践&#xff1a;提高持久层数据处理效率 目录 一、Mybatis简介 1.1 简介1.2 持久层框架对比1.3 快速入门&#xff08;基于Mybatis3方式&#xff09; 二、MyBatis基本使用 2.1 向SQL语句传参 2.1.1 mybatis日志输出配置2.1.2 #{}形式2.1.3 ${}形式 2.2 数据输入 2…

cesium 包络线

cesium 包络线 以下为源码直接复制可用 1、实现思路 通过turf.js中union方法来计算包络线官方地址:https://turfjs.fenxianglu.cn/ 闪烁线请查看cesium轨迹线(闪烁轨迹线) 2、示例代码 <!DOCTYPE html> <html lang="en"&g

SpringBoot配置第三方专业缓存技术Memcached 下载 安装 整合测试 2024年5000字详解

Memcached下载和安装 是一个国内使用量还是比较大的技术 打开文件夹 我们需要在命令行窗口启动 注意要以管理员方式运行 先尝试进入指定文件 然后又再次运行 下载 memcached.exe -d install 启动 memcached.exe -d start 停止 memcached.exe -d stop memcached.exe -d i…

Mysql数据库约束的概述 , 逐渐约束 , 主键自增 , 表关系的概念和外键 ,多表关系约束介绍和使用

约束和表设计 1、DQL查询语句-limit语句(掌握) 目标 能够掌握limit语句的使用 讲解 作用&#xff1a; LIMIT是限制的意思&#xff0c;所以LIMIT的作用就是限制查询记录的条数。 LIMIT语句格式: select * from 表名 limit offset, row_count; mysql中limit的用法&#…

轻松恢复丢失数据EasyRecovery你的数据守护神

数据丢失&#xff1f;别怕&#xff01;EasyRecovery来帮忙 大家好呀&#xff0c;今天我要分享一个我超级喜欢的数据恢复软件——EasyRecovery&#xff01;&#x1f389; 如果你也经历过误删文件、硬盘格式化或是意外丢失重要数据的尴尬和焦虑&#xff0c;那你一定要看看这个神器…

Bytebase 对接本地部署的 llama3 开启ChatSQL功能

Bytebase 是为开发人员、测试、DBA和运维工程师构建的数据库 DevOps 领域的&#xff0c;类 GitLab/GitHub 平台。 这篇文章主要关注 Bytebase SQL 编辑器中的 AI 增强功能。使用此功能您可以使用自然语言在 Bytebase SQL 编辑器中查询数据库。同时还能给出针对查询的索引建议&…

千呼新零售2.0【更新日志】持续更新ing

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货等连锁店使用。 详细介绍请查看下…

【CSS in Depth 2 精译】1.5 渐进式增强

文章目录 1.5 渐进式增强1.5.1 利用层叠规则实现渐进式增强1.5.2 渐进式增强的选择器1.5.3 利用 supports() 实现特性查询启用浏览器实验特性 1.5 渐进式增强 要用好 CSS 这样一门不断发展演进中的语言&#xff0c;其中一个重要的因素就是要与时俱进&#xff0c;及时了解哪些功…

HTML静态网页成品作业(HTML+CSS)——动漫猪猪侠网页(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有4个页面。 二、作品演示 三、代…

测试辅助工具(抓包工具)的使用4 之 断点

抓包作用3&#xff08;绕过界面限制测试&#xff09; 1.为什么要绕过界面限制做测试&#xff1f; 原因&#xff1a;界面限制导致部分异常数据无法输入 2.如何绕过界面限制做测试&#xff1f; 绕过界面限制直接测试服务器 步骤&#xff1a; 1.设置断点 2.修改请求 3.修改响应…

微型操作系统内核源码详解系列五(五):cm3下Pendsv切换任务上篇

系列一&#xff1a;微型操作系统内核源码详解系列一&#xff1a;rtos内核源码概论篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列二&#xff1a;微型操作系统内核源码详解系列二&#xff1a;数据结构和对象篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列…