QProgressDialog用法及结合QThread用法,四种线程使用

1 QProgressDialog概述

QProgressDialog类提供耗时操作的进度条。
进度对话框用于向用户指示操作将花费多长时间,并演示应用程序没有冻结。此外,QPorgressDialog还可以给用户一个中止操作的机会。
进度对话框的一个常见问题是很难知道何时使用它们;操作在不同的硬件上花费不同的时间。QProgressDialog为这个问题提供了一个解决方案:它估计操作将花费的时间(基于步骤的时间),并且仅在估计超过minimumDuration()(默认为4秒)时才显示它自己。
使用setMinimum()setMaximum()或构造函数设置操作中的“steps”数,并在操作进行时调用setValue()steps数可以任意选择。它可以是复制的文件数、接收的字节数、通过算法主循环的迭代次数,或者其他合适的单位。进度从setMinimum()设置的值开始,当使用setMaximum()设置的值作为参数调用setValue()时,进度对话框显示操作已经完成。
在操作结束时,对话框会自动重置并隐藏自己。使用setAutoReset()setAutoClose()来改变这种行为。
注意,如果设置了一个新的最大值(使用setMaximum()setRange()),它等于你的当前值(),无论如何对话框都不会关闭。

QProgressDialog progress;
progress.setMaximun(100);
Progress.setValue(100);

以上代码,对话框不会自动隐藏。
QProgressDialog有两种使用方式:模态和非模态。
与非模态QProgressDialog相比,模态QProgressDialog对于程序员来说更容易使用。在循环中执行操作,每隔一段时间调用setValue(),并使用wasCanceled()检查是否取消。
例如:

QProgressDialog progress("复制文件...", "中止", 0, numFiles, this);
      progress.setWindowModality(Qt::WindowModal);

      for (int i = 0; i < numFiles; i++) {
          progress.setValue(i);

          if (progress.wasCanceled())
              break;
          // 开始复制
	      // ......
      }
	   // 复制完成,将最大值设置给当前值,对话框自动隐藏,关闭
      progress.setValue(numFiles);

在这里插入图片描述

2 QProgressDialog常用函数

2.1 构造函数:

  • QProgressDialog(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()):创建一个默认的进度对话框,parent是对话框的父部件,f是对话框的窗口标志。
  • QProgressDialog(const QString &labelText, const QString &cancelButtonText, int minimum, int maximum, QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()):创建一个带有文本标签、取消按钮和进度范围的进度对话框。labelText是标签的文本,cancelButtonText是取消按钮的文本,minimum和maximum指定了进度的范围。

2.2 成员函数:

  • void cancel():重置进度对话框,将wasCanceled()标记为true,直到进度对话框被重置。进度对话框将隐藏起来。
  • void canceled():在点击取消按钮时发射的信号,默认与cancel()槽连接。
  • void open(QObject *receiver, const char *member):打开对话框,并将其canceled()信号连接到receiver对象的member槽上。
  • void reset():重置进度对话框,如果autoClose()为true,则对话框将隐藏。
  • void setBar(QProgressBar *bar):设置进度条部件。
  • void setCancelButton(QPushButton *cancelButton):设置取消按钮部件。
  • void setCancelButtonText(const QString &cancelButtonText):设置取消按钮的文本。
  • void setLabel(QLabel *label):设置标签部件。
  • void setRange(int minimum, int maximum):设置进度范围。
  • QSize sizeHint() const:返回适合对话框内容的大小。

2.3 常用方法示例代码

CustomProgress::CustomProgress(QWidget *parent) : QProgressDialog(parent)
{
    // 设置窗体Flags, 对话框 | 只有关闭按钮,无问号
    this->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
    // 设置取消按钮文本
    this->setCancelButtonText("取消");


    // 设置进度条区间,等同分别设置最小值  和  最大值
    setRange(0, 100);
    // 设置最小值
    setMinimum(0);
    // 设置最大值
    setMaximum(100);

    // 设置当前值
    setValue(0);

    // 设置文本,一般在进度条上方显示
    setLabelText("helloworld");
    
    // 设置自动关闭,当reset()时,对话框自动关闭,默认为true
    setAutoClose(true);
    // 设置自动重置,当reset()或当前值 == 最大值时,重置
    setAutoReset(true);


    connect(this, &CustomProgress::canceled, this, &CustomProgress::cancel);

    // 设置对话框窗体标题
    this->setWindowTitle("等待...");
}

3 线程Qthread

当在主线程里,进行耗时操作,然后加载进度对话框时,会发现,对话框进度条会卡死不动,然后耗时操作结束,对话框进度条直接关闭,界面感官不友好。
因此需要将耗时操作放到线程内操作,主线程就进行进度显示。界面也不会卡死。

QThread类提供了一种独立于平台的方式来管理线程。
QThread对象管理程序中的一个控制线程。QThreadsrun()中开始执行。默认情况下,run()通过调用exec()启动事件循环,并在线程内运行Qt事件循环。

此外,还可以通过使用QObject::moveToThread()将工作对象移动到线程中来使用它们。

下面是四种线程使用方式与进度框相结合,模拟处理耗时操作,主界面显示进度。

3.1 继承QThread,重写run()方法

.h

class C_Thread : public QThread
{
    Q_OBJECT
public:
    explicit C_Thread(int nMax, QObject *parent = nullptr);

    virtual void run() override;

signals:
    void emit_sendValue(int nValue);

private:
    int     m_nMax;
};

.cpp

#include "Thread.h"

C_Thread::C_Thread(int nMax, QObject *parent) : QThread(parent), m_nMax(nMax)
{

}

void C_Thread::run()
{
    int i = 0;
    while (i < m_nMax) {
        msleep(100);
        ++i;
        emit emit_sendValue(i);
    }
}

当进行start()时,自动调用run(),每过100ms,发送一个数据,主界面进行显示

3.2 继承QObject,之后添加到线程moveToThread(),使用信号和槽方式

需要将进行耗时操作的类,移动到线程中,之后以信号和槽的方式和进度框进行交互
.h

class C_ThreadObject : public QObject
{
    Q_OBJECT
public:
    explicit C_ThreadObject(int nMax, QObject *parent = nullptr);

signals:
    void emit_sendValue(int nValue);

public slots:
    void slot_dealValue();

private:
    int     m_nMax;
};

.cpp

C_ThreadObject::C_ThreadObject(int nMax, QObject *parent) : QObject(parent), m_nMax(nMax)
{

}

void C_ThreadObject::slot_dealValue()
{
    int i = 0;
    while (i < m_nMax) {
        QThread::msleep(100);
        ++i;
        emit emit_sendValue(i);
    }
}

3.3 继承QRunnable

重写run(),然后通过线程池调用
.h

class C_ThreadRunnable :public QObject, public QRunnable
{
    Q_OBJECT
public:
    explicit C_ThreadRunnable(int nMax);

signals:
    void emit_sendValue(int nValue);

public slots:

protected:
    virtual void run() override;

private:
    int m_nMax;
};

.cpp

C_ThreadRunnable::C_ThreadRunnable(int nMax) : m_nMax(nMax)
{

}

void C_ThreadRunnable::run()
{
    int i = 0;
    while (i < m_nMax) {
        QThread::msleep(100);
        ++i;
        emit emit_sendValue(i);
    }
}

3.4 使用QtConcurrent模块

Qt Concurrent模块扩展了Qt Core模块中的基本线程支持,简化了可以在所有可用CPU内核上并行执行的代码开发。
.h

void MainWindow::dealValue()
{
    int i = 0;
    while (i < m_nMax) {
        QThread::msleep(100);
        ++i;
        emit emit_sendValue(i);
    }
}

.cpp

QtConcurrent::run(this, &MainWindow::dealValue);

3.5 主线程调用

创建各个线程对象,然后进行模拟耗时操作,进度框显示进度
如果在构造中new过QProgressDialog对象,默认4秒后,会自动显示,可以调用其close()方法,不用显示。
.h

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    void dealValue();

signals:
    void emit_start();

    void emit_sendValue(int nValue);

private slots:
    void on_btn_TimeConsumingOperation_clicked();

private:
    Ui::MainWindow *ui;
    int                   m_nMax;

    C_DlgProgress*        m_pDlgProgress;
    C_Thread*             m_pTread;
    C_ThreadRunnable*     m_pThreadRunnable;

    C_ThreadObject*       m_pThreadObject;
    QThread*              m_pThreadUsedObject;
};

.cpp

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

#include <QThreadPool>
#include <QtConcurrent>
#include <QDebug>


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

    m_nMax = 20;

    m_pDlgProgress = new C_DlgProgress(this);
    m_pDlgProgress->setRange(0, m_nMax);

    // 1. 继承QThread
    m_pTread = new C_Thread(m_nMax, this);
    connect(m_pTread, &C_Thread::emit_sendValue, this, [=](int nValue){
        m_pDlgProgress->setValue(nValue);
    });

    // 2. 继承QRunnable
    m_pThreadRunnable = new C_ThreadRunnable(m_nMax);
    connect(m_pThreadRunnable, &C_ThreadRunnable::emit_sendValue, this, [=](int nValue){
        m_pDlgProgress->setValue(nValue);
    });

    // 3. 继承QObject
    m_pThreadObject = new C_ThreadObject(m_nMax);
    connect(this, &MainWindow::emit_start, m_pThreadObject, &C_ThreadObject::slot_dealValue);
    connect(m_pThreadObject, &C_ThreadObject::emit_sendValue, this, [=](int nValue){
        m_pDlgProgress->setValue(nValue);
    });
    m_pThreadUsedObject = new QThread(this);
    m_pThreadObject->moveToThread(m_pThreadUsedObject);
    m_pThreadUsedObject->start();

    // 0. 在主线程处理耗时操作
    connect(this, &MainWindow::emit_sendValue, this, [=](int nValue){
        m_pDlgProgress->setValue(nValue);
    });
}

MainWindow::~MainWindow()
{
    if(m_pThreadUsedObject)
    {
        m_pThreadUsedObject->quit();
        m_pThreadUsedObject->wait();
    }

    delete ui;
}

void MainWindow::dealValue()
{
    int i = 0;
    while (i < m_nMax) {
        QThread::msleep(100);
        ++i;
        emit emit_sendValue(i);
    }
}

void MainWindow::on_btn_TimeConsumingOperation_clicked()
{
    m_pDlgProgress->show();
    // 0. 在主线程模拟处理耗时操作,界面卡死
    //    int i = 0;
    //    while (i < m_nMax) {
    //        QThread::msleep(100);
    //        ++i;
    //        emit emit_sendValue(i);
    //    }

    /*********** 使用哪个,打开哪个注释  ***********/

    // 1. 继承QThread
    // m_pTread->start();

    // 2. 继承QRunnable
    // QThreadPool::globalInstance()->start(m_pThreadRunnable);

    // 3. 继承QObject
    // emit emit_start();

    // 4. 使用QtConcurrent模块
    // QtConcurrent::run(this, &MainWindow::dealValue);
}

3.6 结果

主界面显示:
在这里插入图片描述

点击耗时操作
在这里插入图片描述
当进度走完,进度框关闭。

4 完整示例连接

链接: https://download.csdn.net/download/MrHHHHHH/88692241?spm=1001.2014.3001.5501

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

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

相关文章

ASP.NET Core基础之图片文件(一)-WebApi访问静态图片

阅读本文你的收获&#xff1a; 学会在WebApi项目中访问静态图片了解静态文件中间件UseStaticFiles的用法 系统中免不了要去处理图片文件&#xff0c;比如上传商品的图片、显示商品的图片&#xff0c;访问系统中的图片等等&#xff0c;根据微软官网描述&#xff1a; 静态文件&a…

阿里巴巴开源异构数据源离线/全量/增量同步工具 - DataX

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

android——自定义TextView

效果展示&#xff1a; 代码解析&#xff1a; 1、首先设置自定义属性&#xff08;res/values下新建一个attrs.xml文件&#xff09; <?xml version"1.0" encoding"utf-8"?> <resources><!-- name 自定义view的名字 CustomTextView--&…

假期归来必看!2023年9月份,爆款论文总结,了解最新学术进展!

以下文章来源于AINLPer &#xff0c;作者ShuYini 十一假期结束了&#xff0c;十月基本上算是过了一半了&#xff0c;小伙伴们收收心准备开始学习工作吧。按照惯例&#xff0c;月初继续带到家盘一下上个月(九月份)的热点论文。本月论文主要分为大模型微调、大模型发布、大模型应…

jmeter线程组

特点&#xff1a;模拟用户&#xff0c;支持多用户操作&#xff1b;可以串行也可以并行 分类&#xff1a; setup线程组&#xff1a;初始化 类似于 unittest中的setupclass 普通线程组&#xff1a;字面意思 teardown线程组&#xff1a;环境恢复&#xff0c;后置处理

泰国Cafe Racer卖到日本去了还限量150台?

GPX推出日本限定 GTM250R Cafe Racer&#xff0c;复古小车卖到日本去了&#xff0c;限量150台&#xff0c;不得不说这台小车还是挺有味道的。现代的复古风格摩托车也是永远都不会落伍&#xff0c;即使没有什么品牌背书&#xff0c;喜欢这种车型的人&#xff0c;对于配置动力都不…

Uniapp使用wx.getFuzzyLocation()方法,没有超过日调用次数,报错:“此key每日调用已达到上限”

前言&#xff1a; 最近在进行一个小程序项目开发的时候&#xff0c;使用wx.getFuzzyLocation()方法&#xff0c;没有超过日调用次数&#xff0c;但是却出现了报错&#xff1a;“此key每日调用已达到上限”。 解决方案&#xff1a; 打开腾讯位置服务 - 立足生态&#xff0c;连…

学习Go语言Web框架Gee总结--http.Handler(一)

学习Go语言Web框架Gee总结--http.Handler http-base/go.modhttp-base/main.gohttp-base/gee/gee.gohttp-base/gee/go.mod 网站学习来源&#xff1a;Gee 代码目录结构&#xff1a; http-base/go.mod //指定当前模块的名称为 "example" module example//指定当前模…

Python入门学习篇(十七)——封装、继承、多态

1 封装 1.1 理解 属性和方法书写到类里面的操作即为封装 封装可以理解成私有化属性和私有化方法1.2 示例代码 class Person():p_num 0 # 用于统计数量def __init__(self, name, age, sex, job):# __name为私有化属性self.__name nameself.age ageself.sex sexself.job …

一种可扩展的多属性可控文本生成即插即用方法

《An extensible plug-and-play method for multi-aspect controllable text generation》论文解读 文章的主要工作 &#xff08;1&#xff09;提出了一种可扩展的即插即用方法&#xff0c;PROMPT GATING&#xff0c;用于多方面可控文本生成&#xff0c;它能够通过简单地连接…

引导和服务

一、Linux操作系统引导过程 1、引导过程总览图 2、引导过程的详细步骤 1.开机自检&#xff08;BIOS&#xff09; 服务器主机开机以后&#xff0c;将根据主板BIOS中的设置对CPU、内存、显卡、键盘等设备进行初步检测&#xff0c;检测成功后根据预设的启动顺序移交系统控制权&a…

【MySQL】数据库之主从复制和读写分离

目录 一、什么是读写分离&#xff1f; 二、为甚要读写分离&#xff1f; 三、什么时候需要读写分离&#xff1f; 四、主从复制与读写分离 五、MySQL支持的二进制日志格式 六、主从复制的工作原理 七、MySQL读写分离的原理 八、MySQL读写分离的方式有哪些 九、实验一&am…

Windows 7 虚拟机的安装以及解决安装VMVMware tools问题

1.Windows 7 虚拟机的安装以及解决安装VMVMware tools问题 参考&#xff1a;Windows 7 虚拟机的安装以及解决安装VMVMware tools问题 注意&#xff1a;下载官方补丁&#xff1a;Microsoft Update Catalog在智慧联想浏览器中打不开&#xff0c;要在火狐中才能打开下载。 2.win7如…

Navicat(数据库可视化软件)安装教程以及连接MYSQL

Navicat安装教程以及连接MYSQL Navicat&#xff08;数据库可视化软件&#xff09;安装流程安装MySQLnavicat连接mysql数据库 Navicat&#xff08;数据库可视化软件&#xff09; Navicat 是一款专门为 MySQL 设计的可视化数据库 GUI 管理工具&#xff0c;我们可以在自己的计算机…

【HarmonyOS开发】共享包HAR和HSP的创建和使用以及三方库的发布

OpenHarmony提供了两种共享包&#xff0c;HAR&#xff08;Harmony Archive&#xff09;静态共享包&#xff0c;和HSP&#xff08;Harmony Shared Package&#xff09;动态共享包。 HAR与HSP都是为了实现代码和资源的共享&#xff0c;都可以包含代码、C库、资源和配置文件&…

Windows可以ping通ubuntu,但ubuntu无法ping通windows

使用了NAT网卡和桥接网卡&#xff0c;电脑连了WiFi&#xff0c;桥接网卡桥接到WLAN上&#xff0c;Windows可以ping通Ubuntu但反过来不行&#xff01; 1.可能是防火墙的问题&#xff0c;按照如下设置&#xff0c;无果 考虑是不是使用了两个网卡冲突了&#xff0c;取消NAT的链接 …

【Mybatis】Mybatis如何防止sql注入

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; Mybatis ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 1、使用参数化的 SQL 语句&#xff1a; 2、使用动态 SQL 标签&#xff1a; 3、禁止拼接 SQL&#xff1a; 4、限制参数类…

SkyWalking 快速入门

SkyWalking 是一个基于 Java 开发的分布式系统的应用程序性能监视工具&#xff0c;专为微服务、云原生架构和基于容器&#xff08;Docker、K8s、Mesos&#xff09;架构而设计。 一、SkyWalking 简介 SkyWalking 是观察性分析平台和应用性能管理系统。 提供分布式追踪、服务网格…

SpringBoot的基础配置

问题导入 入门案例中没有引入spring-webmvc等依赖包&#xff0c;没有配置Tomcat服务器&#xff0c;为什么能正常启动&#xff1f;我们没有配置端口号&#xff0c;为什么端口是8080&#xff1f; 起步依赖 starter SpringBoot中常见项目名称&#xff0c;定义了当前项目使用的所…

AUTOSAR软件架构描述文档,AUTOSAR_EXP_LayeredSoftwareArchitecture

AUTOSAR软件架构描述文档&#xff0c;我们常见的经典的CP架构及OS双核等架构描述 下载链接&#xff1a;https://www.autosar.org/fileadmin/standards/R21-11/CP/AUTOSAR_EXP_LayeredSoftwareArchitecture.pdf
最新文章