QT中通过TCP协议多线程的文件传输(客户端)

首先,新建一个项目,我命名为了SendFileClient

 首先我们要在pro文件中 代码第一行加入network的后缀

 

一、窗口搭建

 如图所示,在第一个QWidget中让客户端输入IP端口号   连接服务器

第二个Qwidget 设置一个LineEdit,供客户端选择要发送的文件

在下面设置一个 progressBar ,用来显示文件上传的进度

在最下面设置一个按钮点击发送文件。

二、创建一个新类

既然运用到了多线程,我们将连接服务器,选择文件,发送文件的任务交给子线程,主线程去管理进度条的任务

右键项目add new新建一个类 

继承Qobject,这里我取名为sendfile

在sendfile.h中定义两个函数用来连接服务器,发送文件

mainwindow的操作

连接服务器

首先在mainwindow的构造函数中 初始化 ip ,端口号进度条 的值

我要将发送文件连接服务器在子线程中操作的话,我们就要先创建一个线程对象和任务对象,将任务对象通过moveToThread函数移动到创建出来的线程中去工作。

 接下来我们实现 连接服务器的操作

右键ui中的连接服务器转到槽函数的clicked()

 函数中的内容

 要提前在mainwindow.h在定义一个信号,提醒worker对象中的connectSever开始执行

 

 在上面的构造函数中,用connect如果收到startConnect的信号,就去执行woker中的connectSever函数

然后启动子线程用start()

看到这先去看sendfile操作再回来看下面的  1

 这时主线程收到了子线程发来的connectOK,就知道成功连接到了服务器
如果收到了gameover,就知道服务器断开了,进行资源释放

发送文件

给选择文件添加一个处理函数 

发送文件同样

 提前在mainwindow.h中添加好这个信号

 在mainwindow的构造函数中添加一个connect表示如果我收到了发来的sendfile信号,就去完成sendfile类中的send函数

这里跳转到sendfile后面观看  2

 更新进度条

在构造函数中添加connect,如果收到curpencent信号,将信号中传来的pencent去设置进度条的值

mainwindow到这也结束了

sendfile的操作

1

现在sendfile.h文件中定义一个QTcpSocket的套接字,用于通信

 

 完善一下connectSever操作

 提前在sendfile.h中先定义好信号;

第一次看到这可以回去看了

2

将文件发送给服务器,将文件传输进度通过信号告诉主线程

提前添加一个curpencent的信号

这时回到主窗口更新进度条,senfile到这一步就完成了

完整代码

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include"sendfile.h"
#include<QThread>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTsignals:void startconnect(unsigned short ,QString);void sendfile(QString path);public:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_pushButton_clicked();void on_selFile_clicked();void on_sendFile_clicked();private:Ui::MainWindow *ui;QThread *t;sendFile * work;
};#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QMessageBox>
#include<QFileDialog>
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);ui->ip->setText("127.0.0.1");ui->port->setText("8899");ui->progressBar->setRange(0,100);ui->progressBar->setValue(0);t = new QThread;work = new sendFile; //实例化一个sendfile类work->moveToThread(t);//将实例化的类要执行的程序移动到线程里去执行connect(this,&MainWindow::sendfile,work,&sendFile::send);connect(this,&MainWindow::startconnect,work,&sendFile::connectSever);//如果点击连接按钮,这里会接收到一个startconnct的槽函数,然后去执行work中的connctSever操作connect(work,&sendFile::connectOK,this,[=](){ //如果connctsever连接成功,会发来一个connctok的槽函数QMessageBox::information(this,"连接服务器","连接服务器成功");});connect(work,&sendFile::gameover,this,[=](){  //如果断开连接会发来一个gameover的槽函数t->quit();t->wait();t->deleteLater();work->deleteLater();});connect(work,&sendFile::curpencent,ui->progressBar,&QProgressBar::setValue);t->start();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_clicked()
{unsigned short port = ui->port->text().toUShort();//将ui中的端口号转换为short类型取出保存QString ip = ui->ip->text().toUtf8();//将对象转换为UTF-8编码的字节序列,存储在QString对象中,emit startconnect(port,ip);//发送一个开始连接的信号
}void MainWindow::on_selFile_clicked()
{QString path = QFileDialog::getOpenFileName();//通过此方法可以得到某个磁盘文件的绝对路径if(path.isEmpty()){QMessageBox::warning(this,"选择文件","选择的文件不能为空");//如果选择文件为空弹出一个警告对话窗return;}ui->filePath->setText(path);//将选择好的文件设置给文本框
}void MainWindow::on_sendFile_clicked()
{emit sendfile(ui->filePath->text());//因为发送文件的操作是在子线程中做的,所以发送一个信号告诉子线程文件路径名
}

sendfile.h

#ifndef SENDFILE_H
#define SENDFILE_H#include <QObject>
#include<QTcpSocket>
#include <QHostAddress>class sendFile : public QObject
{Q_OBJECT
public:explicit sendFile(QObject *parent = nullptr);void connectSever(unsigned short port, QString ip);//连接服务器void send(QString path);//发送文件signals:void connectOK();void gameover();void curpencent(int );private:QTcpSocket *tcp;};#endif // SENDFILE_H

sendfile.cpp

#include "sendfile.h"
#include <QFile>
#include <QFileInfo>
#include <QHostAddress>sendFile::sendFile(QObject *parent) : QObject(parent)
{}void sendFile::connectSever(unsigned short port, QString ip)
{tcp = new QTcpSocket;//实例化套接字tcp->connectToHost(QHostAddress(ip),port);//通过给定的ip,port连接服务器connect(tcp,&QTcpSocket::connected,this,&sendFile::connectOK);//如果连接成功就发送一个connectOK的信号告诉主线程connect(tcp,&QTcpSocket::disconnected,[=](){//如果断开连接就关闭套接字并释放,发送gameover的信号给主线程tcp->close();tcp->deleteLater();emit  gameover();});
}void sendFile::send(QString path)
{// 创建一个QFile对象,将要发送的文件与该对象关联QFile file(path);QFileInfo info(path);// 创建一个QFileInfo对象,用于获取文件的元信息,如大小等file.open(QFile::ReadOnly); // 打开文件为只读模式int fileSize = info.size();// 获取文件的大小while(!file.atEnd())// 当文件未读到末尾时,循环读取文件{static int num = 0; // 定义一个静态变量num,用于累计已读取的字节数if(num == 0)// 如果是第一次读取,则发送文件的大小信息{tcp->write((char *)&fileSize, 4);// 将文件大小的前4个字节写入tcp套接字,以通知接收端文件的大小num = 4;// 将静态变量num设置为4,因为已经发送了文件大小的前4个字节}QByteArray line = file.readLine(); // 读取一行数据num += line.size();// 将读取的字节数累加到numint percent = (num * 100 / fileSize); // 计算已读取的字节数占总字节数的百分比tcp->write(line);// 将读取的数据行写入tcp套接字emit curpencent(percent);// 发射信号,通知界面文件传输的进度}
}

main.cpp

#include "mainwindow.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

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

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

相关文章

报表系统之Redash

Redash 是一个开源的数据可视化和仪表板工具&#xff0c;旨在帮助用户轻松地从多个数据源中提取、查询、可视化数据&#xff0c;并分享结果。它的设计目标是让数据分析变得更加便捷&#xff0c;即使是非技术用户也能通过简单的操作生成复杂的数据报告和仪表板。 核心概念和功能…

sql基础语句题练

此篇文章所有题都来源于牛客网 牛客网在线编程_SQL篇_非技术快速入门 记录一下自己的做题的历程&#xff0c;废话不多说直接开整 1.查询所有列 select * from user_profile user_profile代表表table的意思 2.查询多列 select device_id,gender,age,university from user…

[godot] 采用状态机时,如何处理攻击时移动?如“冲撞”

这里以‘史莱姆撞击’为例子&#xff0c;将‘空中跃进’定义为伤害帧。&#xff08;见下图&#xff09; 先梳理流程&#xff1a;a.史莱姆原地蓄力(起跳准备)--->b.跳起并移动一段距离(空中跃进)--->c.落地调整 一 当状态机进入‘攻击状态’时&#xff0c;在enter()中…

计算机毕业设计PySpark+Django农产品推荐系统 农产品爬虫 农产品商城 农产品大数据 农产品数据分析可视化 PySpark Hadoop

基于Spark的农产品个性推荐系统 相关技术介绍: 1. Python Python是一种高级编程语言&#xff0c;具有简洁、易读、易学的特点&#xff0c;被广泛应用于Web开发、数据分析、人工智能等领域。 在此系统中&#xff0c;我们使用Python进行后端开发&#xff0c;利用其强大的语法…

基本数据类型 --- 浮点型

float的机器码表示&#xff1a; 一个float数据 (pow(-1, sign) fraction) * pow(2, exponent - 127) 由上图&#xff0c;可得&#xff1a; (pow(-1, sign) fraction) * pow(2, exponent - 127) ( 1 2^(-2) ) * pow(2, 124-127) 0.15625 其他文章&#xff1a; https://b…

Docker Swarm部署SpringCloud Alibaba微服务踩坑记录

为了方便部署和维护微服务项目&#xff0c;还是得上集群部署方案&#xff0c;决定采用Docker的swarm&#xff0c;为什么不是k8s&#xff0c;因为部署骑来又是个新的工具&#xff0c;之前就一直用的docker&#xff0c;自带了类k8s的工具&#xff0c;索性就直接使用swarm了&#…

力扣(K件物品的最大和)

数据量小不需要考虑时间复杂度 数学思维理清楚步骤---然后代码翻译实现 Ⅰ、 K件物品的最大和 袋子中装有一些物品&#xff0c;每个物品上都标记着数字 1 、0 或 -1 。 给你四个非负整数 numOnes 、numZeros 、numNegOnes 和 k 。 袋子最初包含&#xff1a; numOnes 件标…

鸿蒙HarmonyOS之使用ArkTs语言实现层级树状目录选择UI

一、实现效果 二、实现步骤 代码示例中用到的颜色、图片等资源可以自行替换设置 1、Index.ets 里面调用 import { CategoryView} from ./CategoryView;//主页面 Entry Component struct Index {State tabsIndex: number 0;build() {...//层级目录ViewCategoryView()...} …

ReTagList标签列表(API)

组件实现基于 Vue3 + Element Plus + Typescript,同时引用 vueUse + lodash-es + tailwindCss (不影响功能,可忽略) 基于ElTag实现的Tag列表,支持Tag列表多选,动态Tag列表 ReTagList标签列表 基础 简单展示Tag列表,可通过size指定尺寸 查看 /demo/tag-list/basic.md …

Arduino开源四足蜘蛛机器人制作教程

视频教程&#xff1a;手把手叫你做四足蜘蛛机器人——1零件介绍_哔哩哔哩_bilibili 一、项目介绍 1.1 项目介绍 Arduino主控&#xff0c;图形化编程&#xff0c;趣味学习 Arduino nano开发板舵机扩展底板 4.8V可充电电池&#xff0c;支持Arduino C语言编程和米思齐图形化编程…

Spring Cloud Config 与 Spring Cloud Bus 来实现动态配置文件

要使用 Spring Cloud Config 与 Spring Cloud Bus 来实现动态配置文件&#xff0c;你可以按照以下步骤操作&#xff1a; ### 步骤 1: 添加依赖 首先&#xff0c;确保你的项目中添加了 Spring Cloud Config 客户端和 Bus 的依赖。对于 Maven 项目&#xff0c;pom.xml 文件应该…

浅谈Kafka(一)

浅谈Kafka&#xff08;一&#xff09; 文章目录 浅谈Kafka&#xff08;一&#xff09;Kafa的设计是什么样的数据传输的事务定义消息队列的应用场景Kafka怎么样判断节点是否存活Kafka的消息是采用pull模式还是push模式Kafka在磁盘上的消息格式Kafka高效文件存储设计特点Kafka与传…

Yolov10网络详解与实战(附数据集)

文章目录 摘要模型详解模型实战训练COCO数据集下载数据集 COCO转yolo格式数据集&#xff08;适用V4&#xff0c;V5&#xff0c;V6&#xff0c;V7&#xff0c;V8&#xff09;配置yolov10环境训练断点训练测试 训练自定义数据集Labelme数据集格式转换训练测试 总结 摘要 模型详解…

CeresPCL 岭回归拟合(曲线拟合)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 由于在使用最小二乘插值拟合时,会涉及到矩阵求逆的操作,但是如果这个矩阵接近于奇异时,那么拟合的结果就会与我们期望的结果存在较大差距,因此就有学者提出在最小二乘的误差函数中添加正则项,即: 这里我们也可…

OpenGL-ES 学习(8) ---- FBO

目录 FBO OverViewFBO 优点使用FBO的步骤 FBO OverView FBO(FrameBuffer Object) 指的是帧缓冲对象&#xff0c;实际上是一个可以添加缓冲区容器&#xff0c;可以为其添加纹理或者渲染缓冲区对象(RBO) FBO(FrameBuffer Object) 本身不能用于渲染&#xff0c;只有添加了纹理或者…

对派生类指针使用C风格的强制类型转换为基类指针

以下来自语言大模型的回答&#xff1a; 值可能发生改变 当对派生类指针使用C风格的强制类型转换成基类指针时&#xff0c;指针的值可能会发生改变。这主要是由于多重继承和虚继承的存在。以下是几个关键点解释: 单继承情况下: 在单继承的情况下&#xff0c;派生类指针转换为…

Stability AI发布了单目视频转4D模型的新AI模型:Stable Video 4D

开放生成式人工智能初创公司Stability AI在3月发布了Stable Video 3D&#xff0c;是一款可以根据图像中的物体生成出可旋转的3D模型视频工具。Stability AI在7月24日发布了新一代的Stable Video 4D&#xff0c;增添了赋予3D模移动作的功能。 Stable Video 4D能在约40秒内生成8…

数字乡村+智慧农业数字化转型大数据平台建设方案

1. 数字农业发展趋势 数字农业正经历全环节数字技术应用、全流程生产经营再造、全方位线上线下对接和管理服务全生命周期覆盖的四大趋势&#xff0c;标志着我国农业进入高质量发展新阶段。 2. 数字乡村的战略意义 数字乡村作为数字化、网络化和信息化的产物&#xff0c;对于…

Wemos D1 Mini pro/ nodeMcu / ESP8266 驱动 240*320 ILI9431 SPI液晶屏

Wemos D1 Mini / nodeMcu / ESP8266 驱动 240*320 ILI9431 SPI液晶屏 效果展示器件硬件连接引脚连接原理图引脚对照表 安装TFT_eSPI库TFT_eSPI库中User_Setup.h文件的参数修改User_Setup.h文件的位置User_Setup.h文件中需要修改的参数User_Setup.h完成源码 例程 缘起&#xff1…