Qt中实时更新UI程序示例

2023-11-01

1. 概述

Qt在运行时会开启一个主线程,如果没有开启工作线程的话,所有界面上的操作都是在主线程,包括更新界面或者处理数据等操作。我们都知道如果处理数据比较多的话,最好是在单独开启一个线程来处理数据,这样就不会影响主线程的运行。

2. 开发环境

Windows系统:Windows10

Qt版本:Qt5.15或者Qt6

3. 实时更新UI(非信号与槽)

QT中不建议工作线程中更新界面。

workthread.h

#ifndef WORKTHREAD_H
#define WORKTHREAD_H

#include <QThread>

class MainWindow;
class QLabel;

class WorkThread : public QThread
{
    Q_OBJECT
public:
    WorkThread(QObject *parent);
    ~WorkThread();

    void setObject(MainWindow *obj);
    void setLabel(QLabel *l);
    void stop();

protected:
    void run();


private:
    MainWindow *mainObject = nullptr;
    QLabel *label = nullptr;
    int i = 0;

    volatile bool stopped = false;
};

#endif // WORKTHREAD_H

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

workthread.cpp

#include "workthread.h"
#include "mainwindow.h"

#include <QLabel>
#include <QDebug>

WorkThread::WorkThread(QObject *parent):QThread(parent)
{
    stopped = false;
}


WorkThread::~WorkThread()
{

}


void WorkThread::setObject(MainWindow *obj)
{
    mainObject = obj;
}

void WorkThread::setLabel(QLabel *l)
{
    label = l;
}


void WorkThread::run()
{
    qDebug() << "线程开始运行";
    
    while(!stopped)
    {
        msleep(1);
        i++;
        //mainObject->runInThread();
        label->setText(QString("当前计数为:%1").arg(i));
    }
    //下次启动
    stopped = false;
}

//暂停线程
void WorkThread::stop()
{
    stopped = true;
    qDebug() << "线程已经暂停";
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include "workthread.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class WorkThread;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void runInThread();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::MainWindow *ui;

    WorkThread *thread = nullptr;

    int count = 0;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "workthread.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    thread = new WorkThread(this);
    thread->setObject(this);
    thread->setLabel(ui->label);

    ui->pushButton->setEnabled(true);
    ui->pushButton_2->setEnabled(false);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::runInThread()
{
    count++;

    ui->label->setText(QString("当前计数为: %1").arg(count));
}

//启动线程
void MainWindow::on_pushButton_clicked()
{
    if (nullptr != thread)
    {
        thread->start();
    }

    ui->pushButton->setEnabled(false);
    ui->pushButton_2->setEnabled(true);
}

//暂停线程
void MainWindow::on_pushButton_2_clicked()
{
    if (nullptr != thread)
    {
        thread->stop();
    }

    ui->pushButton->setDisabled(false);
    ui->pushButton_2->setDisabled(true);
}

主界面

 

4. 实时更新UI(信号与槽)

workthread.h

#ifndef WORKTHREAD_H
#define WORKTHREAD_H

#include <QThread>

class MainWindow;
class QLabel;


struct Student
{
    int id;
    char sex;
    QString name;
};

//声明元类型
Q_DECLARE_METATYPE(Student)

class WorkThread : public QThread
{
    Q_OBJECT
public:
    WorkThread(QObject *parent);
    ~WorkThread();

    void stop();

protected:
    void run();

signals:
    void sigCount(Student s);

private:

    int i = 0;

    volatile bool stopped = false;
};

#endif // WORKTHREAD_H

workthread.cpp

#include "workthread.h"
#include "mainwindow.h"

#include <QLabel>
#include <QDebug>

WorkThread::WorkThread(QObject *parent):QThread(parent)
{
    //注册自定义类型
    qRegisterMetaType<Student>();

    stopped = false;
}

WorkThread::~WorkThread()
{

}

void WorkThread::run()
{
    qDebug() << "线程开始运行";

    while(!stopped)
    {
        i++;

        //发送信号
        Student s;
        s.id = i;
        s.sex = 'M';
        s.name = "lily";
        emit sigCount(s);

        msleep(1);
    }

    //下次启动
    stopped = false;
}

//暂停线程
void WorkThread::stop()
{
    stopped = true;
    qDebug() << "线程已经暂停";
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include "workthread.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class WorkThread;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void slotSetValue(Student s);

private:
    Ui::MainWindow *ui;

    WorkThread *thread = nullptr;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "workthread.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    thread = new WorkThread(this);

    ui->pushButton->setEnabled(true);
    ui->pushButton_2->setEnabled(false);

    connect(thread, &WorkThread::sigCount, this, &MainWindow::slotSetValue);
}

MainWindow::~MainWindow()
{
    delete ui;
}


//启动线程
void MainWindow::on_pushButton_clicked()
{
    if (nullptr != thread)
    {
        thread->start();
    }

    ui->pushButton->setEnabled(false);
    ui->pushButton_2->setEnabled(true);
}

//暂停线程
void MainWindow::on_pushButton_2_clicked()
{
    if (nullptr != thread)
    {
        thread->stop();
    }

    ui->pushButton->setDisabled(false);
    ui->pushButton_2->setDisabled(true);
}

//槽函数
void MainWindow::slotSetValue(Student( s))
{
    ui->label->setText(QString("当前值为: %1 %2 %3").arg(s.id).arg(s.sex).arg(s.name));
}

主界面

 

【温馨提示】

如果要在Qt信号槽中使用自定义类型,需要注意使用qRegisterMetaType对自定义类型进行注册,当然在不跨线程时使用自定义类型signal/slot来传递,可能不会出现什么问题;一旦涉及跨线程就很容易出错,回想下信号槽的作用就是用来对象与对象之间通信的,难免会跨线程,建议在使用自定义类型利用信号槽通信时,最好先通过qRegisterMetaType()将自定义类型进行注册,以免出错。

总结qRegisterMetaType使用方法如下:

1、注册位置:在第一次使用此类链接跨线程的signal/slot之前,一般在当前类的构造函数中进行注册;

2、注册方法:在当前类的顶部包含:#include ,构造函数中加入代码:qRegisterMetaType(“Myclass”);

3、Myclass的引用类型需单独注册:qRegisterMetaType(“Myclass&”);

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt中实时更新UI程序示例 的相关文章

  • 如何向 PyQt5 GUI 添加线程?

    所以我使用 QT Designer 创建了一个 GUI 它工作得很好 但在更复杂的调用中 它不会更新主窗口并锁定 我想运行我的CustomComplexFunction 在根据不断变化的后端信息更新主窗口中的文本编辑时 我希望它每 2 秒运
  • 使 QLabel 的像素图透明

    我有一个带有 QLabel 和像素图的主窗口 我想让它透明 或不那么不透明 我正在使用下面的代码 ui gt label gt setAttribute Qt WA TranslucentBackground ui gt label gt
  • 在 Qt GraphicsView 中创建长线(或十字线)光标的最佳方法

    创建长十字线光标 与视口一样长 的简单方法是创建一条十字线graphicsItem 当鼠标移动时 设置该项目的pos财产 但是当场景复杂时这种方式会很慢 因为它要更新整个视口来更新光标的pos 另一种简单的方法是setCursor QCur
  • 使用 QGraphicsScene 和 QGraphicsView 在 Qt 中开始基于 Tile 的游戏

    我将开始在 Qt 中编写基于 2D 图块的游戏 并阅读 QGraphicsScene 和 QGraphicsView 类 这些类旨在显示和处理大量 2D 对象 我的问题是 使用 QGraphicsScene 创建一个包含大量图块的世界是否可
  • Qt 相当于 .NET 数据绑定吗?

    Qt 中是否有相当于 NET 数据绑定的功能 我想使用引用数据库中特定实体的 QString 填充一些组合框和其他小部件 但是 如果我可以将数据绑定到这些字符串 而不是基于新的组合框选择再次查询数据库 或者基于构建我自己的将使用 QStri
  • CMake AUTOMOC,文件位于不同文件夹中

    我有一个简单的 CMake 项目 proj project folder a h a cpp CMakeLists txt CMakeLists txt cmake minimum required VERSION 3 2 set CMAK
  • QByteArray 到整数

    正如您可能从标题中看出的那样 我在转换QByteArray为一个整数 QByteArray buffer server gt read 8192 QByteArray q size buffer mid 0 2 int size q siz
  • 一个具有完全透明背景的qt小部件

    我需要创建一个 qt 小部件 它将充当其他一些小部件的父级 并对它们进行排序 现在的问题是如何使其背景完全透明 我想这样做 struct Imp Imp QWidget parent thisWidget new QWidget paren
  • Qt 和 Sqlite 示例

    我正在寻找一些使用 Qt 的示例代码 它是带有 Sqlite 驱动程序的 SQL 模块 我需要示例的主要原因是我之前有 Qt 数据库接口的经验 并且 Sqlite 在字段类型方面有一些奇怪的行为 类型是按字段存储的 而不是按列存储的 The
  • Qt 文本选择白线和文本宽度

    我想在 QTextEdit 中自定义文本选择 我想要两件事 选择时删除空格 线条 能够选择选择的宽度 或者小部件宽度 或文本宽度 空白 线条 通常 我想要的是 来自 Bear 应用程序 熊文本选择 在使用 QTextEdit 小部件时 我注
  • Qt:使用 QObject::connect 指定多种连接类型

    我想知道是否可以指定多种连接类型 例如 我希望我的连接类型是排队连接和唯一连接 是否可以在一份声明中具体说明这一点 QObject connect ptrSender SIGNAL ptrReceiver SLOT Queued and u
  • Android 上的 QT 应用程序中的 java.nio.channels.OverlappingFileLockException

    我的 QT 应用程序崩溃了java nio channels OverlappingFileLockException例外Nokia 1具有以下调用堆栈的设备 FATAL EXCEPTION dbp processing com googl
  • 如何释放Qthread对象的内存?

    我做过这样的事情 in the mainwindow s constructor QThread thr new QThread soundWorker work new soundWorker connect this SIGNAL pl
  • Qt 覆盖小部件快捷方式(窗口快捷方式)

    我有一个 Qt 应用程序 其中在 Qt Designer 表单操作中定义了多个窗口快捷方式 这些快捷键效果很好 直到焦点位于处理相同组合的小部件上 覆盖我的窗口快捷键 时按下它们 我想要相反的行为 窗口快捷方式覆盖聚焦的小部件快捷方式 我尝
  • Qt 要包含哪些标头?

    使用 Qt 使用 C 进行编程时 我应该包含哪些内容 仅包含 2 个 include
  • 超越堆栈采样:C++ 分析器

    黑客的故事 日期是 2010 年 2 月 12 日 圣诞节前的日子已经过去了 作为一名 Windows 程序员 我几乎遇到了一个主要障碍 我一直在使用 AQTime 我尝试过 sleepy shiny very sleepy 就在我们说话的
  • Qt 中的智能指针[重复]

    这个问题在这里已经有答案了 就像已经写过一样here http blog qt digia com 2009 08 25 count with me how many smart pointer classes does qt have Q
  • 如何禁用滚轮事件 QGraphicsView Qt C++ 上的滚动功能

    我有一个图形视图 并且我设置了自己的功能 以便在用户按下 Control 并单击鼠标时手动拖动滚动 我已经删除了滚动条 但鼠标滚轮仍然会滚动 甚至滚动到显示在图像中的图像qGraphicsView显示我的手拖动没有的空白 白色 空间 我怎样
  • 如何将 qmake 转换为 cmake?

    我有一个 pro我的项目上的文件 但现在我想将其移植到CMakeLists txt文件 我怎样才能做到这一点 QT core QT gui CONFIG c 11 TARGET test CONFIG console CONFIG app
  • 防止 QGraphicsItem 移出 QGraphicsScene

    我有一个场景 其固定尺寸从 0 0 到 481 270 scene gt setSceneRect 0 0 481 270 在里面 我有一个习惯GraphicsItem多亏了旗帜我可以移动它ItemisMovable 但我希望它留在场景中

随机推荐

  • Mybatis的代码自动生成插件(Free Mybatis plugin)

    介绍 使用的是Free Mybatis plugin代码生成插件 在idea的plugins中可以搜索到 并且是免费的 唯一的不足就是 代码如果重新生成 会被覆盖掉 所以需要手动的进行合并源代码 不过通过git可以比较好的解决该问题 安装
  • 算法导论:钢条切割问题方法全解(递归+动态规划)

    public class Main public static void main String args Main main new Main int p 0 1 5 8 9 10 17 17 20 24 30 System out pr
  • python网络爬虫--基本概念(1)

    一 爬虫简介 1 1 爬虫的定义 网络爬虫 又被称为网页蜘蛛 网络机器人 在FOAF社区中间 更经常的称为网页追逐者 是一种按照一定的规则 自动批量化地抓取万维网信息的程序或者脚本 自动批量化的抓取既有数据 模拟客户端发送请求 接受数据 1
  • PMP题目与解题思路(第五天)

    PMP题目与解题思路 第五天 41 在一次社交集会中 一位团队成员无意中告诉一位相关方项目已经落后于进度计划 并且构成重大延迟 与项目经理沟通该问题时 该相关方非常激动 此时项目经理应该怎么做 A 同团队回顾风险管理计划 B 创建相关方影响
  • 使用JQgrid常用 (实战经常用)

    jqgrid参数 jqGrid参数 名称 类型 描述 默认值 可修改 url string 获取数据的地址 datatype string 从服务器端返回的数据类型 默认xml 可选类型 xml local json jsonnp scri
  • stm32智能小车设计

    提前说说 博主是用寄存器写的驱动 历时两周 总算把小车弄好了 总体上来说做的太慢了 自己在32的学习中还不够仔细深入 只是浅面的学习 当真正做一个项目时 暴露的问题就太多了 这次在小车的制作的过程中 遇到了各种各样的问题 软件 硬件 各式各
  • openwrt上opkg更新报错"opkg_download: Failed to download ............."

    開始搞op的时候 看到op居然能够直接安装一些插件 激动坏了 由于这东西对嵌入式的小系统来说简直不敢想 可是op就支持了 就是这么任性 好不easy编译了固件 依照网上的教程 telnet进去 首先opkg update 结果没有想象中的华
  • discuz密码找回:[1]忘记UCENTER创始人密码

    人们都是健忘的 何况每天的事情很多 有些站长更是兼职做 赚点外快而已 而ucenter更是不常用 所以忘记密码是在正常不过的事情 如果密码忘记怎么找回呢 方法有很多种 例如用comsenz tools工具 但是这个有版本问题 有些人怕装上出
  • LeetCode:4.寻找两个正序数组中的中位数(median-of-two-sorted-arrays)思路与题解

    LeetCode 4 寻找两个正序数组中的中位数 median of two sorted arrays 包含输入的完整代码LeetCode 4 寻找两个正序数组中的中位数 median of two sorted arrays Java完
  • 报错 java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 解决方案

    Android项目报错 java lang IndexOutOfBoundsException Index 0 Size 0 我忘记截图了哈哈哈 记录一下错误原因 找了老半天 ok 出现这种错误是数组值没有取到 我们可以在取值之前加一个判断
  • 微信人人商城云服务器,微信支付 · 微智人人商城使用文档 · 看云

    支付管理 添加新模板 https box kancloud cn a39c011c0de721adce0ebef9b95162d4 1151x763 png 公众号appid获取方法 登陆公众平台 左侧导航 开发 基本配置 开发者ID AP
  • C# 将时间戳 byte[] 转换成 datetime 的几个方法

    推荐方法 DateTime now DateTime Now byte bts BitConverter GetBytes now ToBinary DateTime rt DateTime FromBinary BitConverter
  • LLM的用法

    一 生成表格 推测以下评价内容的情绪 情绪只包括 客观 积极 消极 输出表格 格式 编号 段落前10个字摘要 情绪判断 1 这东西给用户最大的门槛就是 描述是否精准 你描述的越精准 他给你的答案也就越精准 所以那些根本不知道自己需求是什么的
  • Android面试必备的JVM虚拟机制详解,看完之后简历上多一个技能!

    掌握了本篇知识之后 简历上就可以多加一条个人技能了 熟悉 JVM 相关知识 包括内存区域 内存模型 GC 类加载机制 编译优化等 下面就是正文了 欢迎讨论 目录 内存区域 内存模型 内存分配回收策略 Java 对象的创建 内存布局和访问定位
  • 蓝桥杯 算法训练 拿金币(java)

    蓝桥杯 算法训练 拿金币 java 题 试题 算法训练 拿金币 资源限制 时间限制 1 0s 内存限制 256 0MB 问题描述 有一个N x N的方格 每一个格子都有一些金币 只要站在格子里就能拿到里面的金币 你站在最左上角的格子里 每次
  • 6.ES基础概念及术语详细解读

    一 Elasticsearch概述 ES是基于Lucene的搜索服务器 它提供了一个分布式多用户能力的全问搜索引擎 且ES支持RestFulweb风格的url访问 ES是基于Java开发的开源搜索引擎 设计用于云计算 能够达到实时搜索 稳定
  • js数组的顺序排序、完全随机打乱排序 总结

    一 顺序排序 1 按字符编码排序 sort var testArray 23 500 1000 300 34 2 testArray sort alert testArray 2 1000 23 300 34 500 2 将数组元素倒序排
  • unittest测试框架+ddt数据驱动

    unittest测试框架 unittest测试框架 四个核心组件 TestCase Testfixure TestSuite testRunner assert impront unittest测试框架 在编写接口自动化测试用例时 如果不采
  • nginx 部署多个vue项目

    这里写目录标题 vue项目配置 env staging文件 env production文件 vuefig js文件 router gt index js文件 nginx配置 ngxin下载后解压即可 1 vue项目配置 基于若依框架的前端
  • Qt中实时更新UI程序示例

    1 概述 Qt在运行时会开启一个主线程 如果没有开启工作线程的话 所有界面上的操作都是在主线程 包括更新界面或者处理数据等操作 我们都知道如果处理数据比较多的话 最好是在单独开启一个线程来处理数据 这样就不会影响主线程的运行 2 开发环境