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.rhkb.cn/news/28963.html

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

相关文章

【算法day2】无重复字符的最长子串 两数之和

无重复字符的最长子串 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 https://leetcode.cn/problems/longest-substring-without-repeating-characters/ class Solution { public:int lengthOfLongestSubstring(string s) {int sub_length …

XHR请求解密:抓取动态生成数据的方法

在如今动态页面大行其道的时代&#xff0c;传统的静态页面爬虫已无法满足数据采集需求。尤其是在目标网站通过XHR&#xff08;XMLHttpRequest&#xff09;动态加载数据的情况下&#xff0c;如何精准解密XHR请求、捕获动态生成的数据成为关键技术难题。本文将深入剖析XHR请求解密…

【漫话机器学习系列】121.偏导数(Partial Derivative)

偏导数&#xff08;Partial Derivative&#xff09;详解 1. 引言 在数学分析、机器学习、物理学和工程学中&#xff0c;我们经常会遇到多个变量的函数。这些函数的输出不仅取决于一个变量&#xff0c;而是由多个变量共同决定的。那么&#xff0c;当其中某一个变量发生变化时&…

[C语言日寄] 字符串操作函数的使用及其拓展

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…

计算机毕业设计Python+Django+Vue3微博数据舆情分析平台 微博用户画像系统 微博舆情可视化(源码+ 文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

ssm_mysql_暖心家装平台

收藏关注不迷路&#xff01;&#xff01; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff08;免费咨询指导选题&#xff09;&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;希望帮助更多…

地下井室可燃气体监测装置:守护地下安全,防患于未“燃”!

在城市的地下&#xff0c;隐藏着无数的燃气管道和井室&#xff0c;它们是城市基础设施建设的重要部分&#xff0c;燃气的使用&#xff0c;给大家的生活提供了极大的便利。在便利生活的背后&#xff0c;也存在潜在的城市安全隐患。 近年来&#xff0c;地下井室可燃气体泄漏事故…

EasyCVR平台赋能农业产业园:AIoT驱动的视频监控与大数据分析解决方案

随着现代农业的快速发展&#xff0c;农业产业园区的规模不断扩大&#xff0c;管理复杂度也随之增加。为了提高农业生产效率、保障农产品质量安全、实现精细化管理和智能化运营&#xff0c;视频信息化建设成为现代农业产业园的重要发展方向。EasyCVR作为一款功能强大的视频监控与…

【三维生成】StarGen:基于视频扩散模型的可扩展的时空自回归场景生成

标题&#xff1a;《StarGen: A Spatiotemporal Autoregression Framework with Video Diffusion Model for Scalable and Controllable Scene Generation》 项目&#xff1a;https://zju3dv.github.io/StarGen 来源&#xff1a;商汤科技、浙大CAD、Tetras.AI 文章目录 摘要一、…

STM32 进阶 定时器

在stm32中定时器大概分为4类 1、系统定时器&#xff1a;属于arm内核&#xff0c;内嵌在NVIC中 2、高级定时器&#xff1a;可以用来刹车和死区 3、通用定时器&#xff1a;可以用来输出pwm方波 4、基本定时器&#xff1a;只能记数 系统定时器注意&#xff1a; 1、系统定时器…

day21-API(算法,lambda,练习)

常见的七种查找算法&#xff1a; ​ 数据结构是数据存储的方式&#xff0c;算法是数据计算的方式。所以在开发中&#xff0c;算法和数据结构息息相关。今天的讲义中会涉及部分数据结构的专业名词&#xff0c;如果各位铁粉有疑惑&#xff0c;可以先看一下哥们后面录制的数据结构…

正则表达式梳理(基于python)

正则表达式&#xff08;regular expression&#xff09;是一种针对字符串匹配查找所定义的规则模式&#xff0c;独立于语言&#xff0c;但不同语言在实现上也会存在一些细微差别&#xff0c;下面基于python对常用的相关内容进行梳理。 文章目录 一、通用常识1.通配符ps.反义 2.…

Java多线程与高并发专题——为什么 Map 桶中超过 8 个才转为红黑树?

引入 JDK 1.8 的 HashMap 和 ConcurrentHashMap 都有这样一个特点&#xff1a;最开始的 Map 是空的&#xff0c;因为里面没有任何元素&#xff0c;往里放元素时会计算 hash 值&#xff0c;计算之后&#xff0c;第 1 个 value 会首先占用一个桶&#xff08;也称为槽点&#xff…

Llama-Factory框架下的Meta-Llama-3-8B-Instruct模型微调

目录 引言 Llama - Factory 训练框架简介&#xff1a; Meta - Llama - 3 - 8B - Instruct 模型概述&#xff1a; Lora 方法原理及优势&#xff1a; 原理 优势 环境准备: 部署环境测试&#xff1a; 数据准备&#xff1a; 模型准备&#xff1a; 模型配置与训练&#xff1…

介绍一个能支持高带宽的EDID编辑软件

软件名称叫980 Manager 4.24.16&#xff0c;安装后的图标如下。   软件可以去此地址下载https://download.csdn.net/download/cjie221/90459603&#xff0c;下载后需解压&#xff0c;运行.msi文件安装。   安装后&#xff0c;打开软件&#xff0c;首先会弹出这个界面&…

2025年Cursor最新安装使用教程

Cursor安装教程 一、Cursor下载二、Cursor安装三、Cursor编辑器快捷键(1) 基础编辑快捷键(2) 导航快捷键(3) 其他常用快捷键 一、Cursor下载 Cursor官方网站&#xff08;https://www.cursor.com/ &#xff09; 根据自己电脑操作系统选择对应安装包 二、Cursor安装 下载完成后…

[内网安全] Windows 本地认证 — NTLM 哈希和 LM 哈希

关注这个专栏的其他相关笔记&#xff1a;[内网安全] 内网渗透 - 学习手册-CSDN博客 0x01&#xff1a;SAM 文件 & Windows 本地认证流程 0x0101&#xff1a;SAM 文件简介 Windows 本地账户的登录密码是存储在系统本地的 SAM 文件中的&#xff0c;在登录 Windows 的时候&am…

pt-archiver删除数据库的数据表/各种报错类型

这篇帖子是前面文的一部分延申 mysqlimport导入一亿数据的csv文件/一行命令删除表-CSDN博客 如需转载&#xff0c;标记出处 目录 pt-archiver命令格式 如果执行后出现下面报错 1&#xff09;Cannot find an ascendable index in table at /usr/bin/pt-archiver line 3233. …

开发环境搭建-06.后端环境搭建-前后端联调-Nginx反向代理和负载均衡概念

一.前后端联调 我们首先来思考一个问题 前端的请求地址是&#xff1a;http://localhost/api/employee/login 后端的接口地址是&#xff1a;http://localhost:8080/admin/employee/login 明明请求地址和接口地址不同&#xff0c;那么前端是如何请求到后端接口所响应回来的数…

自学Linux系统软件编程第八天

并发服务器&#xff1a; 服务器在同一时刻可以响应多个客户端的请求。 UDP&#xff1a;无连接 单循环服务器&#xff1a;服务器同一时刻只能响应一个客户端的请求。 TCP&#xff1a;有连接 构建TCP并发服务器&#xff1a; 让TCP服务端具备同时响应多个客户端的能力。 方法…