Qt 进度条与多线程应用、基于 Qt 的文件复制工具开发

练习1:Qt 进度条与多线程应用

题目描述

开发一个基于 Qt 的应用程序,该应用程序包含一个水平进度条(QSlider),并且需要通过多线程来更新进度条的值。请根据以下要求完成代码:

  1. 界面设计

    • 使用 QSlider 控件作为进度条。

    • 设置 QSlider 的样式

  2. 多线程更新

    • 创建一个自定义线程类 mythread,该线程类继承自 QThread

    • 使主线程接收到信号后,更新 QSlider 的值。

  3. 信号与槽

    • 使用信号与槽机制实现线程与主线程之间的通信。

    • 当线程中的值发生变化时,通过信号通知主线程更新进度条。

1.mythread.h 

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include<QThread>class mythread : public QThread
{Q_OBJECT
public:explicit mythread(QObject *parent = nullptr);void run() override; // 线程的执行函数signals:void updateValue(int value); // 发送信号更新进度条
};#endif // MYTHREAD_H

2.mythread.cpp 

#include "mythread.h"
#include<QThread>mythread::mythread(QObject *parent){}
void mythread::run()
{int value = 0;while (true) {emit updateValue(value);value = (value + 1) % 101;  // 0 ~ 100 循环QThread::msleep(100);  // 休眠 100ms}
}

3.widget.h 

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QWidget>
#include <QMovie>
#include <QThread>
#include <QTextEdit>
#include <QWidget>
#include <QThread>
#include<QScreen>
#include<QLabel>
#include<QDebug>
#include<QPixmap>
#include<QApplication>
#include<QPushButton>
#include "mythread.h"QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECT
public slots:void setSliderValue(int value); // 更新进度条public:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;mythread *thread;
};
#endif // WIDGET_H

4.widget.cpp 

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QString qss = "QSlider { background: transparent; }"//设置 QSlider 的背景为透明"QSlider::groove:horizontal { border: 1px solid gray; background: lightgray; height: 15px; border-radius: 5px; }""QSlider::sub-page:horizontal { background: #B5E61D; border-radius: 5px; }""QSlider::handle:horizontal { background:#5A730E; width: 10px;border-radius: 5px }";ui->horizontalSlider->setStyleSheet(qss);// 创建并启动线程thread = new mythread(this);connect(thread, &mythread::updateValue, this, &Widget::setSliderValue);thread->start();}Widget::~Widget()
{delete ui;
}// 槽函数:更新进度条
void Widget::setSliderValue(int value)
{ui->horizontalSlider->setValue(value);
}

练习2:基于 Qt 的文件复制工具开发

开发一个基于 Qt 的文件复制工具,要求实现以下功能:

  1. 文件选择

    • 使用 QFileDialog 选择源文件和目标文件。

    • 支持选择大文件(超过 800MB)。

  2. 文件复制

    • 使用 Qt 的文件 IO 操作(QFile)实现文件复制功能。

    • 支持分块读取和写入文件,避免一次性加载大文件到内存中。

  3. 多线程处理

    • 使用 QThread 在后台执行文件复制操作,避免阻塞主线程。

    • 通过信号与槽机制,将复制进度实时传递给主线程。

  4. 进度显示

    • 使用自定义的 QSlider 作为进度条,显示文件复制的进度。

    • 自定义 QSlider 的样式,使其外观美观。

  5. 错误处理

    • 如果文件打开失败或复制失败,弹出错误提示框。

    • 如果复制完成,弹出提示框显示“文件复制完成”。

1.mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QThread>
#include <QString>class MyThread : public QThread
{Q_OBJECTpublic:explicit MyThread(const QString &source, const QString &destination, QObject *parent = nullptr);signals:void progressUpdated(int value); // 信号:用于更新进度条的值protected:void run() override; // 线程执行函数private:QString sourcePath;  // 源文件路径QString destinationPath; // 目标文件路径
};#endif // MYTHREAD_H

2.mythread.cpp 

#include "mythread.h"
#include <QFile>
#include <QDebug>MyThread::MyThread(const QString &source, const QString &destination, QObject *parent): QThread(parent), sourcePath(source), destinationPath(destination)
{
}void MyThread::run()
{QFile sourceFile(sourcePath);QFile destinationFile(destinationPath);// 打开源文件if (!sourceFile.open(QIODevice::ReadOnly)) {emit progressUpdated(-1); // 发送错误信号return;}// 打开目标文件if (!destinationFile.open(QIODevice::WriteOnly)) {emit progressUpdated(-1); // 发送错误信号return;}qint64 fileSize = sourceFile.size(); // 获取文件大小qint64 bytesCopied = 0; // 已复制的字节数char buffer[4096]; // 缓冲区// 分块读取和写入文件while (!sourceFile.atEnd()) {qint64 bytesRead = sourceFile.read(buffer, sizeof(buffer)); // 读取数据destinationFile.write(buffer, bytesRead); // 写入数据bytesCopied += bytesRead; // 更新已复制的字节数int progress = static_cast<int>((bytesCopied * 100) / fileSize); // 计算进度emit progressUpdated(progress); // 发送进度信号}// 关闭文件sourceFile.close();destinationFile.close();
}

3.widget.h 

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QSlider>
#include <QFileDialog>
#include <QMessageBox>
#include "mythread.h"QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void updateProgress(int value); // 槽函数:更新进度条private:Ui::Widget *ui;MyThread *thread; // 文件复制线程
};#endif // WIDGET_H

 4.widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QMessageBox>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 设置 QSlider 的样式QString qss = "QSlider { background: transparent; }" // 设置 QSlider 的背景为透明"QSlider::groove:horizontal { border: 1px solid gray; background: lightgray; height: 15px; border-radius: 5px; }""QSlider::sub-page:horizontal { background: #B5E61D; border-radius: 5px; }""QSlider::handle:horizontal { background:#5A730E; width: 10px; border-radius: 5px; }";ui->horizontalSlider->setStyleSheet(qss);ui->horizontalSlider->setRange(0, 100); // 设置进度条范围ui->horizontalSlider->setValue(0); // 初始值为 0// 选择源文件QString sourceFile = QFileDialog::getOpenFileName(this, "选择要复制的文件");if (sourceFile.isEmpty()) {QMessageBox::warning(this, "警告", "未选择源文件");return;}// 选择目标文件QString destinationFile = QFileDialog::getSaveFileName(this, "选择保存位置");if (destinationFile.isEmpty()) {QMessageBox::warning(this, "警告", "未选择目标文件");return;}// 创建并启动线程thread = new MyThread(sourceFile, destinationFile, this);connect(thread, &MyThread::progressUpdated, this, &Widget::updateProgress);thread->start();
}Widget::~Widget()
{if (thread) {thread->quit(); // 停止线程thread->wait(); // 等待线程结束delete thread; // 释放线程对象}delete ui;
}// 槽函数:更新进度条
void Widget::updateProgress(int value)
{if (value == -1) {QMessageBox::critical(this, "错误", "文件复制失败");return;}ui->horizontalSlider->setValue(value); // 更新 QSlider 的值if (value == 100) {QMessageBox::information(this, "完成", "文件复制完成");}
}

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

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

相关文章

Gartner:数据安全平台DSP提升数据流转及使用安全

2025 年 1 月 7 日&#xff0c;Gartner 发布“China Context&#xff1a;Market Guide for Data Security Platforms”&#xff08;《数据安全平台市场指南——中国篇》&#xff0c;以下简称指南&#xff09;&#xff0c;报告主要聚焦中国数据安全平台&#xff08;Data Securit…

道可云人工智能每日资讯|《奇遇三星堆》VR沉浸探索展(淮安站)开展

道可云元宇宙每日简报&#xff08;2025年3月5日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 《奇遇三星堆》VR沉浸探索展&#xff08;淮安站&#xff09;开展 近日&#xff0c;《奇遇三星堆》VR沉浸探索展&#xff08;淮安站&#xff09;开展。该展将三星堆文…

Spring AI Alibaba + Ollama:国产大模型DeepSeek LLM的低成本AI应用开发认知

写在前面 官方文档很详细&#xff0c;有开发需求可以直接看文档https://java2ai.com/docs/1.0.0-M5.1/get-started/博文内容为一个开发Demo&#xff0c;以及API简单认知理解不足小伙伴帮忙指正 &#x1f603;,生活加油 我看远山&#xff0c;远山悲悯 持续分享技术干货&#xf…

解决:Word 保存文档失败,重启电脑后,Word 在试图打开文件时遇到错误

杀千刀的微软&#xff0c;设计的 Word 是个几把&#xff0c;用 LaTex 写完公式&#xff0c;然后保存&#xff0c;卡的飞起 我看文档卡了很久&#xff0c;就关闭文档&#xff0c;然后 TMD 脑抽了重启电脑 重启之后&#xff0c;文档打不开了&#xff0c;显示 杀千刀的&#xff…

掌握高效大模型任务流搭建术(二):链式流程如何赋能 AI 处理能力提升

前言&#xff1a; 在上一篇文章中&#xff0c;我们初步探索了 LangChain 的基础链式操作——LLMChain。它巧妙地将大语言模型&#xff08;LLM&#xff09;与提示模板&#xff08;Prompt Template&#xff09;相结合&#xff0c;为模型交互逻辑的封装提供了一种简洁而高效的方式…

虚拟卡 WildCard (野卡) 保姆级开卡教程

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 本篇教程为 WildCard 的介绍以及开卡教学&#xff0c;要了解不同平台&#xff08;Grok、Talkatone 等&#xff09;的订阅方式请移步《订阅教程》分类 当我们想要充值国外平台会员时&#xff0c;一般都需要使…

计算机数据库三级刷题总结(博主89分已过,总结的内容分享)

计算机数据库三级刷题总结&#xff08;博主89分已过&#xff0c;总结的内容分享&#xff09; 文章目录 计算机数据库三级刷题总结&#xff08;博主89分已过&#xff0c;总结的内容分享&#xff09;一、 数据库设计阶段二、事务相关三、数据库设计顺序四、数据库三级模式与二层映…

记录一些面试遇到的问题

重载和重写的区别 重载是overload&#xff0c;覆盖是override 重载属于编译时多态&#xff0c;覆盖属于运行时多态 运行时多态和编译时多态 运行时多态指的是在运行的时候才知道要调用哪一个函数&#xff0c;编译时多态是指在编译的时候就知道调用哪一个函数。 运行时多态…

HBuilder X 使用 TortoiseSVN 设置快捷键方法

HBuilder X 使用 TortoiseSVN 设置快捷键方法 单文件&#xff1a;(上锁&#xff0c;解锁&#xff0c;提交&#xff0c;更新) 安装好 TortoiseSVN &#xff0c;或者 按图操作&#xff1a; 1&#xff0c;工具栏中 【自定义快捷键】 2&#xff0c;点击 默认的快捷键设置&…

JmeterHttp请求头管理出现Unsupported Media Type问题解决

JmeterHttp请求头管理出现Unsupported Media Type问题解决 大多数的app与pc端压测的时候都会出现这种情况 当我们在jemter测试当中当中遇见Unsupported Media Type&#xff0c;有一种可能就是我们请求的网页的content-Type的类型与我们测试的时候的类型不一致 解决方法 可以添…

Spring AI 1.0.0-M6 快速开始(一)

Spring AI 1.0.0-M6 入门一、存储库二、依赖管理完整maven 入门 Spring 是JAVA中我们经常使用的框架之一&#xff0c;Spring AI不断的发展迭代目前已经到M6版本据说上半年会出一个稳定版本。 本节提供了如何开始使用Spring AI的M6。 一、存储库 1.0 M6 -添加Spring存储库 需…

顶点着色器和片段着色器

在Unity渲染中&#xff0c;**顶点着色器&#xff08;Vertex Shader&#xff09;和片段着色器&#xff08;Fragment Shader&#xff09;**是图形渲染管线中的两个核心阶段。我们可以通过一个比喻来理解它们的分工&#xff1a;想象你要画一幅由三角形组成的3D模型&#xff0c;顶点…

Impacket工具中的横向渗透利器及其使用场景对比详解

在渗透测试中&#xff0c;横向移动&#xff08;Lateral Movement&#xff09;是指攻击者在获得一个系统的控制权限后&#xff0c;通过网络进一步渗透到其他系统的过程。Impacket 是一款强大的渗透测试工具集&#xff0c;提供了多种实现横向渗透的脚本&#xff0c;常见的工具包括…

设计模式|策略模式 Strategy Pattern 详解

目录 一、策略模式概述二、策略模式的实现2.1 策略接口2.2 具体策略类2.3 上下文类2.4 客户端代码2.5 UML类图2.6 UML时序图 三、优缺点3.1 ✅优点3.2 ❌ 缺点 四、最佳实践场景4.1 适合场景描述4.2 具体场景 五、扩展5.1 继承复用机制和复合策略5.2 对象管理&#xff1a;优化策…

迷你世界脚本显示板管理接口:DisPlayBoard

显示板管理接口&#xff1a;DisPlayBoard 迷你世界 更新时间: 2023-04-26 10:21:14 具体函数名及描述如下: 序号 函数名 函数描述 1 showBoard(...) 对玩家显示显示板 2 hideBoard(...) 对玩家隐藏显示板 3 setBoardPicture 对玩家设置显示板的图片…

尚硅谷爬虫note14

一、scrapy scrapy&#xff1a;为爬取网站数据是&#xff0c;提取结构性数据而编写的应用框架 1. 安装 pip install scrapy 或者&#xff0c;国内源安装 pip install scrapy -i https&#xff1a;//pypi.douban.com/simple 2. 报错 报错1&#xff09;building ‘twisted.te…

merge函数

merge函数 今天在刷lc&#xff0c;从灵神题解中学到的 来源&#xff1a;560. 和为 K 的子数组 - 力扣&#xff08;LeetCode&#xff09; java8 merge()方法被引入到HashMap类中&#xff0c;用于简化键值对操作&#xff0c;在处理键值对时&#xff0c;提供一个重新映射函数来决…

Notepad++ 8.6.7 安装与配置全攻略(Windows平台)

一、软件定位与核心优势 Notepad 是开源免费的代码/文本编辑器&#xff0c;支持超过80种编程语言的高亮显示&#xff0c;相比系统自带记事本具有以下优势&#xff1a; 轻量高效&#xff1a;启动速度比同类软件快30%插件扩展&#xff1a;支持NppExec、JSON Viewer等200插件跨文…

建筑兔零基础自学python记录39|实战词云可视化项目——章节分布10(上)

这次我们来制作《红楼梦》各章节的分布情况&#xff1a; 源代码&#xff1a; import pandas as pd import numpy as np import matplotlib.pyplot as pltdf_hlm pd.read_csv("hlm.txt", names["hlm_texts"]).dropna()df_hlm df_hlm[~df_hlm.hlm_texts.s…

C++:#ifndef 头文件保护机制详解

在C开发中&#xff0c;头文件可能会被多个源文件包含&#xff0c;导致编译错误。为了避免这种情况&#xff0c;我们使用了头文件保护机制&#xff08;防止重复包含&#xff09;。 头文件保护的原理 通过预处理指令#ifndef&#xff08;如果没有定义&#xff09;和#define&…