首页 > 其他分享 >【七】【QT开发应用】跨UI发送信号,跨线程发送信号

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

时间:2024-06-23 18:01:56浏览次数:3  
标签:Widget ui QT sig 发送 score 线程 信号 setdialog

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

结尾

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

标签:Widget,ui,QT,sig,发送,score,线程,信号,setdialog
From: https://blog.csdn.net/m0_74163972/article/details/139872589

相关文章

  • 一问搞懂Linux信号【上】
    Linux信号在Linux系统中的地位仅此于进程间通信,其重要程度不言而喻。本文我们将从信号产生,信号保存,信号处理三个方面来讲解信号。......
  • SpringBoot发送邮件
    SpringBoot集成邮件服务本文将介绍如何使用SpringBoot集成QQ邮箱的邮件服务,实现Java发送邮件功能。开启邮件服务以QQ邮箱为例,首先需要开启SMTP服务。第一步首页点击设置第二步点击账号第三步下滑找到SMTP相关文件服务,获取验证码第四步复制获取到的授权......
  • QT小项目 - 音乐播放器
    目录零.功能简介一.创建项目二.可视化创建页面1.创建按钮2.创建列表3.创建文字4.创建滑动块5.对象查看器三. cmake引入QMediaPlayer模块1.打开CMakeLists.txt2.添加3.完整参考四.完整代码1.widget.h2.widget.cpp3.main.cpp五.总结零.功能简介这是......
  • QT中子工程的创建,以及如何在含有库的子工程项目中引用主项目中的资源文件
    1、背景在qt中创建多项目类型,如下:CustomDll表示其中的一个动态库子项目;CustomLib表示其中的一个静态库子项目;MyWidget表示主项目窗口(main函数所在项目);2、qrc资源的共享如何在CustomDll和CustomLib等子项目中也同样使用MyWidget项目中的qrc资源呢???直接使用即可,因......
  • Gitlab服务器邮箱配置,实现自动为用户发送邮件(注册发送验证链接)
    一.配置前准备工作及说明服务器系统版本:CentOS7postfix,并在终端运行systemctlstatuspostfix检查服务是否已在运行状态,如果显示activate则表示正在运行[root@sage~]$systemctlstatuspostfix●postfix.service-PostfixMailTransportAgentLoaded:loaded(/......
  • Qt版本选择01
    嵌入式推荐用Qt4.8,打包的程序小:Qt4.8.7是Qt4的终结版本,是Qt4系列版本中最稳定最经典的最后支持xp系统的长期支持版本:Qt5.6.3;Qt5.7.0是最后支持xp系统的非长期支持版本。最后提供mysql数据库插件的版本:Qt5.12.3。最后支持win7的版本:Qt5.15系列。Qt6不支持win7最后样式表性能最......
  • C#使用MJpeg实现视频流发送与显示
    1、发送视频流:usingSystem;usingSystem.Collections.Concurrent;usingSystem.Collections.Generic;usingSystem.Drawing;usingSystem.Globalization;usingSystem.IO;usingSystem.Linq;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading.Tasks......
  • Qt入门程序
    一、QtCreator简介    QtCreator为应用程序开发人员提供了一个完整的跨平台、集成开发环境(IDE)以便为桌面、嵌入式和移动设备平台(如Android和ios)创建应用程序。    QtCreator提供了在整个应用程序开发生命周期所需的工具,从创建项目到将应用程序部署......
  • qt 简单实验 一个可以向右侧拖拽缩放的矩形
    1.概要目的是设置一个可以拖拽缩放的矩形,这里仅用右侧的一个边模拟这个过程。就是为了抓住核心,这个便解决了,其他的边也是一样的。而这个更能体现原理。2.代码2.1 resizablerectangle.h#ifndefRESIZABLERECTANGLE_H#defineRESIZABLERECTANGLE_H#include<QWidget>#in......
  • Python发送HTML邮件有哪些步骤?怎么设置?
    Python发送HTML邮件如何实现?Python发送邮件的策略?HTML邮件不仅可以包含丰富的文本格式,还可以插入图片、链接和其他多媒体内容,从而提升邮件的美观性和功能性。AokSend将详细介绍Python发送HTML邮件的主要步骤,帮助开发者轻松实现这一功能。PHP发送HTML邮件:设置服务每个SMTP服......