十四、Qt主机信息与网络编程

一、主机信息

1、主机信息接口

  • QHostInfo:获取主机名称和IP地址
  • QNetWorkInterface:获取主机的所有网络接口,包括子网掩码和广播地址等

(1)使用

项目添加模块
QT       += network

2、实现程序

在这里插入图片描述

(1)创建项目,基于QDialog

在这里插入图片描述

(2)实现功能

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>#include <QHostInfo>
#include <QNetworkInterface>namespace Ui
{
class Dialog;
}class Dialog : public QDialog
{Q_OBJECTprivate:QString protocolName(QAbstractSocket::NetworkLayerProtocol protocol);public:explicit Dialog(QWidget *parent = nullptr);~Dialog();private slots:void on_btnHostIP_clicked();void on_btnClearText_clicked();void on_btnDnsIP_clicked();void on_lookUpHostInfo(QHostInfo host);void on_btnAllAddresses_clicked();void on_btnAllInterface_clicked();private:Ui::Dialog *ui;
};#endif // DIALOG_H
#include "dialog.h"
#include "ui_dialog.h"QString Dialog::protocolName(QAbstractSocket::NetworkLayerProtocol protocol)
{switch (protocol){case QAbstractSocket::IPv4Protocol:return "IPv4 Protocol";break;case QAbstractSocket::IPv6Protocol:return "IPv6 Protocol";break;case QAbstractSocket::AnyIPProtocol:return "AnyIP Protocol";break;default:return "Unknown Protocol";break;}
}Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog)
{ui->setupUi(this);
}Dialog::~Dialog()
{delete ui;
}void Dialog::on_btnHostIP_clicked()
{QString hostName = QHostInfo::localHostName();ui->plainTextEdit->appendPlainText(hostName);QHostInfo hostInfo = QHostInfo::fromName(hostName);QList<QHostAddress> addList = hostInfo.addresses();foreach (auto aHost, addList){if(ui->checkBox->isChecked()){if(aHost.protocol() == QAbstractSocket::IPv4Protocol){ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));ui->plainTextEdit->appendPlainText("本机IP地址:" + aHost.toString());ui->plainTextEdit->appendPlainText("");}}else{ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));ui->plainTextEdit->appendPlainText("本机IP地址:" + aHost.toString());ui->plainTextEdit->appendPlainText("");}}
}void Dialog::on_btnClearText_clicked()
{ui->plainTextEdit->clear();
}void Dialog::on_btnDnsIP_clicked()
{// 异步方式QString hostName = ui->lineEdit->text();ui->plainTextEdit->appendPlainText("正在查询主机信息:" + hostName);QHostInfo::lookupHost(hostName, this, SLOT(on_lookUpHostInfo(QHostInfo)));
}void Dialog::on_lookUpHostInfo(QHostInfo host)
{QList<QHostAddress> addList = host.addresses();foreach (auto aHost, addList){if(ui->checkBox->isChecked()){if(aHost.protocol() == QAbstractSocket::IPv4Protocol){ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));ui->plainTextEdit->appendPlainText("IP地址:" + aHost.toString());ui->plainTextEdit->appendPlainText("");}}else{ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));ui->plainTextEdit->appendPlainText("IP地址:" + aHost.toString());ui->plainTextEdit->appendPlainText("");}}
}void Dialog::on_btnAllAddresses_clicked()
{QList<QHostAddress> addList = QNetworkInterface::allAddresses();foreach (auto aHost, addList){if(ui->checkBox->isChecked()){if(aHost.protocol() == QAbstractSocket::IPv4Protocol){ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));ui->plainTextEdit->appendPlainText("IP地址:" + aHost.toString());ui->plainTextEdit->appendPlainText("");}}else{ui->plainTextEdit->appendPlainText("协议:" + protocolName(aHost.protocol()));ui->plainTextEdit->appendPlainText("IP地址:" + aHost.toString());ui->plainTextEdit->appendPlainText("");}}
}void Dialog::on_btnAllInterface_clicked()
{QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();foreach (auto aInterface, list){if(!aInterface.isValid()){continue;}ui->plainTextEdit->appendPlainText("设备名称: " + aInterface.humanReadableName());ui->plainTextEdit->appendPlainText("硬件地址: " + aInterface.hardwareAddress());QList<QNetworkAddressEntry> entryList = aInterface.addressEntries();foreach (auto aEntry, entryList){ui->plainTextEdit->appendPlainText("  IP地址: " + aEntry.ip().toString());ui->plainTextEdit->appendPlainText("  子网掩码: " + aEntry.netmask().toString());ui->plainTextEdit->appendPlainText("  广播地址: " + aEntry.broadcast().toString());}ui->plainTextEdit->appendPlainText("");}
}

在这里插入图片描述

二、TCP通信

TCP是一种被大多数Internet网络协议(HTTP、FTP等)用于数据传输的低级网络协议,是可靠的、面向流、面向连接的传输协议。

1、相关类

(1)继承关系

QIODeviceQAbstractSocketQTcpSocketQSctpSocketQSslSocket // 加密QUdpSocket			

2、实现服务端程序

在这里插入图片描述

(1)创建项目

(2)添加图标资源

在这里插入图片描述

(3)实现服务器功能

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QTcpSocket>
#include <QTcpServer>
#include <QLabel>namespace Ui
{
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTprivate:QLabel *labListen;QLabel *labSocketState;QTcpServer *tcpServer;QTcpSocket *tcpSocket;public:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();protected:void closeEvent(QCloseEvent *event);private:QString getLocalIP();private slots:void on_newConnection();void on_clientConnected();void on_clientDisconnected();void on_clientStateChanged(QAbstractSocket::SocketState state);void on_clientReadyRead();void on_actStartListen_triggered();void on_actStopListen_triggered();void on_actClearText_triggered();void on_btnSend_clicked();private:Ui::MainWindow *ui;
};#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"#include <QHostInfo>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);labListen = new QLabel("监听状态:");labListen->setMinimumWidth(200);labSocketState = new QLabel("Socket状态:");labSocketState->setMinimumWidth(200);ui->statusBar->addWidget(labListen);ui->statusBar->addWidget(labSocketState);setWindowTitle("服务器:" + getLocalIP());tcpServer = new QTcpServer(this);connect(tcpServer, SIGNAL(newConnection()),this, SLOT(on_newConnection()));}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::closeEvent(QCloseEvent *event)
{if(tcpServer->isListening()){tcpServer->close();}event->accept();
}QString MainWindow::getLocalIP()
{QString hostName = QHostInfo::localHostName();QHostInfo hostInfo = QHostInfo::fromName(hostName);QString loaclIP;QList<QHostAddress> addList = hostInfo.addresses();foreach (auto aHost, addList){if(aHost.protocol() == QAbstractSocket::IPv4Protocol){if(loaclIP.isEmpty()){loaclIP = aHost.toString();}ui->comboBoxAddresses->addItem(aHost.toString());}}return loaclIP;
}void MainWindow::on_newConnection()
{tcpSocket = tcpServer->nextPendingConnection(); //获取socketconnect(tcpSocket, SIGNAL(connected()), this, SLOT(on_clientConnected()));on_clientConnected(); //当前状态已经发送,需要直接调用通知connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(on_clientDisconnected()));connect(tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),this, SLOT(on_clientStateChanged(QAbstractSocket::SocketState)));on_clientStateChanged(tcpSocket->state()); //当前状态已经发送,需要直接调用通知connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(on_clientReadyRead()));}void MainWindow::on_clientConnected()
{ui->plainTextEdit->appendPlainText("**client socket connected");ui->plainTextEdit->appendPlainText("**peer address: " + tcpSocket->peerAddress().toString());ui->plainTextEdit->appendPlainText("**peer port " + QString::number(tcpSocket->peerPort()));
}void MainWindow::on_clientDisconnected()
{ui->plainTextEdit->appendPlainText("**client socket disconnected");tcpSocket->deleteLater();
}void MainWindow::on_clientStateChanged(QAbstractSocket::SocketState state)
{switch (state){case QAbstractSocket::UnconnectedState:labSocketState->setText("socket状态:UnconnectedState");break;case QAbstractSocket::HostLookupState:labSocketState->setText("socket状态:HostLookupState");break;case QAbstractSocket::ConnectingState:labSocketState->setText("socket状态:ConnectingState");break;case QAbstractSocket::ConnectedState:labSocketState->setText("socket状态:ConnectedState");break;case QAbstractSocket::BoundState:labSocketState->setText("socket状态:BoundState");break;case QAbstractSocket::ListeningState:labSocketState->setText("socket状态:ListeningState");break;case QAbstractSocket::ClosingState:labSocketState->setText("socket状态:ClosingState");break;default:break;}
}void MainWindow::on_clientReadyRead()
{//    while(tcpSocket->canReadLine())int nLen = 0;do{char data[1024] = {0};nLen = tcpSocket->readLine(data, 1023);if(nLen > 0){ui->plainTextEdit->appendPlainText(QString::asprintf("[in]: %s", data));}} while(nLen > 0);
}void MainWindow::on_actStartListen_triggered()
{QString IP = ui->comboBoxAddresses->currentText();int port = ui->spinBoxPort->value();QHostAddress addr(IP);tcpServer->listen(addr, port);ui->plainTextEdit->appendPlainText("**开始监听");ui->plainTextEdit->appendPlainText("**服务IP:" + tcpServer->serverAddress().toString());ui->plainTextEdit->appendPlainText("**服务器端口:" + QString::number(tcpServer->serverPort()));ui->actStartListen->setEnabled(false);ui->actStopListen->setEnabled(true);labListen->setText("监听状态:开始");
}void MainWindow::on_actStopListen_triggered()
{if(tcpServer->isListening()){tcpServer->close();ui->actStartListen->setEnabled(true);ui->actStopListen->setEnabled(false);labListen->setText("监听状态:停止");}
}void MainWindow::on_actClearText_triggered()
{ui->plainTextEdit->clear();
}void MainWindow::on_btnSend_clicked()
{QString msg = ui->lineEdit->text();ui->plainTextEdit->appendPlainText("[out] " + msg);ui->lineEdit->clear();ui->lineEdit->setFocus();msg += "\n";QByteArray data = msg.toUtf8();tcpSocket->write(data);
}

3、实现客户端程序

在这里插入图片描述

(1)创建项目

(2)添加图标资源

在这里插入图片描述

(3)实现功能

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QMainWindow>
#include <QTcpSocket>
#include <QLabel>namespace Ui
{
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTprivate:QLabel *labSocketState;QTcpSocket *tcpSocket;public:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();private:QString getLocalIP();private slots:void on_Connected();void on_Disconnected();void on_StateChanged(QAbstractSocket::SocketState state);void on_ReadyRead();void on_btnSend_clicked();void on_actConnect_triggered();void on_actDisconnect_triggered();void on_actClear_triggered();private:Ui::MainWindow *ui;
};#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"#include <QHostInfo>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);labSocketState = new QLabel("Socket状态:");labSocketState->setMinimumWidth(200);ui->statusBar->addWidget(labSocketState);setWindowTitle("客户端:" + getLocalIP());tcpSocket = new QTcpSocket;connect(tcpSocket, SIGNAL(connected()), this, SLOT(on_Connected()));connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(on_Disconnected()));connect(tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),this, SLOT(on_StateChanged(QAbstractSocket::SocketState)));connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(on_ReadyRead()));
}MainWindow::~MainWindow()
{delete ui;
}QString MainWindow::getLocalIP()
{QString hostName = QHostInfo::localHostName();QHostInfo hostInfo = QHostInfo::fromName(hostName);QString loaclIP;QList<QHostAddress> addList = hostInfo.addresses();foreach (auto aHost, addList){if(aHost.protocol() == QAbstractSocket::IPv4Protocol){if(loaclIP.isEmpty()){loaclIP = aHost.toString();}ui->comboBox->addItem(aHost.toString());}}return loaclIP;
}void MainWindow::on_Connected()
{ui->plainTextEdit->appendPlainText("**socket connected");ui->plainTextEdit->appendPlainText("**peer address: " + tcpSocket->peerAddress().toString());ui->plainTextEdit->appendPlainText("**peer port " + QString::number(tcpSocket->peerPort()));
}void MainWindow::on_Disconnected()
{ui->plainTextEdit->appendPlainText("**socket disconnected");
}void MainWindow::on_StateChanged(QAbstractSocket::SocketState state)
{switch (state){case QAbstractSocket::UnconnectedState:labSocketState->setText("socket状态:UnconnectedState");break;case QAbstractSocket::HostLookupState:labSocketState->setText("socket状态:HostLookupState");break;case QAbstractSocket::ConnectingState:labSocketState->setText("socket状态:ConnectingState");break;case QAbstractSocket::ConnectedState:labSocketState->setText("socket状态:ConnectedState");break;case QAbstractSocket::BoundState:labSocketState->setText("socket状态:BoundState");break;case QAbstractSocket::ListeningState:labSocketState->setText("socket状态:ListeningState");break;case QAbstractSocket::ClosingState:labSocketState->setText("socket状态:ClosingState");break;default:break;}
}void MainWindow::on_ReadyRead()
{int nLen = 0;do{char data[1024] = {0};nLen = tcpSocket->readLine(data, 1023);if(nLen > 0){ui->plainTextEdit->appendPlainText(QString::asprintf("[in]: %s", data));}} while(nLen > 0);
}void MainWindow::on_btnSend_clicked()
{QString msg = ui->lineEdit->text();ui->plainTextEdit->appendPlainText("[out] " + msg);ui->lineEdit->clear();ui->lineEdit->setFocus();msg += "\n";QByteArray data = msg.toUtf8();tcpSocket->write(data);
}void MainWindow::on_actConnect_triggered()
{QString IP = ui->comboBox->currentText();int port = ui->spinBox->value();tcpSocket->connectToHost(IP, port);ui->actConnect->setEnabled(false);ui->actDisconnect->setEnabled(true);
}void MainWindow::on_actDisconnect_triggered()
{if(tcpSocket->state() == QAbstractSocket::ConnectedState){tcpSocket->disconnectFromHost();}ui->actConnect->setEnabled(true);ui->actDisconnect->setEnabled(false);
}void MainWindow::on_actClear_triggered()
{ui->plainTextEdit->clear();
}

在这里插入图片描述

三、UDP通信

UDP用户数据报协议,是轻量的、不可靠的、面向数据报、无连接的协议。

1、实现单播/广播程序

在这里插入图片描述

(1)创建项目

(2)添加图标资源

在这里插入图片描述

(3)实现功能

#include "mainwindow.h"
#include "ui_mainwindow.h"#include <QHostInfo>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);labSocketState = new QLabel("Socket状态:");labSocketState->setMinimumWidth(200);ui->statusBar->addWidget(labSocketState);QString localIP = getLocalIP();setWindowTitle("Udp收发器:" + localIP);udpSocket = new QUdpSocket(this);connect(udpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),this, SLOT(on_StateChanged(QAbstractSocket::SocketState)));connect(udpSocket, SIGNAL(readyRead()),this, SLOT(on_SocketReadyRead()));
}MainWindow::~MainWindow()
{delete ui;
}QString MainWindow::getLocalIP()
{QString hostName = QHostInfo::localHostName();QHostInfo hostInfo = QHostInfo::fromName(hostName);QString loaclIP;QList<QHostAddress> addList = hostInfo.addresses();foreach (auto aHost, addList){if(aHost.protocol() == QAbstractSocket::IPv4Protocol){if(loaclIP.isEmpty()){loaclIP = aHost.toString();}ui->comboBox->addItem(aHost.toString());}}return loaclIP;
}void MainWindow::on_StateChanged(QAbstractSocket::SocketState state)
{switch (state){case QAbstractSocket::UnconnectedState:labSocketState->setText("socket状态:UnconnectedState");break;case QAbstractSocket::HostLookupState:labSocketState->setText("socket状态:HostLookupState");break;case QAbstractSocket::ConnectingState:labSocketState->setText("socket状态:ConnectingState");break;case QAbstractSocket::ConnectedState:labSocketState->setText("socket状态:ConnectedState");break;case QAbstractSocket::BoundState:labSocketState->setText("socket状态:BoundState");break;case QAbstractSocket::ListeningState:labSocketState->setText("socket状态:ListeningState");break;case QAbstractSocket::ClosingState:labSocketState->setText("socket状态:ClosingState");break;default:break;}
}void MainWindow::on_SocketReadyRead()
{QByteArray datagram;datagram.resize(udpSocket->pendingDatagramSize());QHostAddress peerAddr;unsigned short peerPort;udpSocket->readDatagram(datagram.data(), datagram.size(), &peerAddr, &peerPort);QString str = datagram.data();QString peer = "[From " + peerAddr.toString() + ":" + QString::asprintf("%d", peerPort) + "] ";ui->plainTextEdit->appendPlainText(peer  + str);
}void MainWindow::on_actStart_triggered()
{quint16 port = ui->spinBoxBindPort->value();if(udpSocket->bind(port)){ui->plainTextEdit->appendPlainText("**已绑定成功");ui->plainTextEdit->appendPlainText("**端口:" + QString::number(udpSocket->localPort()));ui->actStart->setEnabled(false);ui->actStop->setEnabled(true);}
}void MainWindow::on_actStop_triggered()
{udpSocket->abort();ui->actStart->setEnabled(true);ui->actStop->setEnabled(false);ui->plainTextEdit->appendPlainText("**已解除绑定");
}void MainWindow::on_actClear_triggered()
{ui->plainTextEdit->clear();
}void MainWindow::on_pushButton_clicked()
{// 单播QString targetIP = ui->comboBox->currentText();quint16 targetPort = ui->spinBoxPort->value();QHostAddress targetAddr(targetIP);QString msg = ui->lineEdit->text();QByteArray data = msg.toUtf8();udpSocket->writeDatagram(data, targetAddr, targetPort);ui->plainTextEdit->appendPlainText("[out] " + msg);ui->lineEdit->clear();ui->lineEdit->setFocus();
}void MainWindow::on_pushButton_2_clicked()
{// 广播quint16 targetPort = ui->spinBoxPort->value();QString msg = ui->lineEdit->text();QByteArray data = msg.toUtf8();udpSocket->writeDatagram(data, QHostAddress::Broadcast, targetPort);ui->plainTextEdit->appendPlainText("[out] " + msg);ui->lineEdit->clear();ui->lineEdit->setFocus();
}

在这里插入图片描述

2、实现组播程序

在这里插入图片描述

(1)拷贝上一个项目

(2)修改控件

在这里插入图片描述

(3)实现功能

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);labSocketState = new QLabel("Socket状态:");labSocketState->setMinimumWidth(200);ui->statusBar->addWidget(labSocketState);QString localIP = getLocalIP();setWindowTitle("Udp组播收发器:" + localIP);udpSocket = new QUdpSocket(this);connect(udpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),this, SLOT(on_StateChanged(QAbstractSocket::SocketState)));connect(udpSocket, SIGNAL(readyRead()),this, SLOT(on_SocketReadyRead()));}MainWindow::~MainWindow()
{delete ui;
}QString MainWindow::getLocalIP()
{QString hostName = QHostInfo::localHostName();QHostInfo hostInfo = QHostInfo::fromName(hostName);QString loaclIP;QList<QHostAddress> addList = hostInfo.addresses();foreach (auto aHost, addList){if(aHost.protocol() == QAbstractSocket::IPv4Protocol){if(loaclIP.isEmpty()){loaclIP = aHost.toString();}ui->comboBox->addItem(aHost.toString());}}return loaclIP;
}void MainWindow::on_StateChanged(QAbstractSocket::SocketState state)
{switch (state){case QAbstractSocket::UnconnectedState:labSocketState->setText("socket状态:UnconnectedState");break;case QAbstractSocket::HostLookupState:labSocketState->setText("socket状态:HostLookupState");break;case QAbstractSocket::ConnectingState:labSocketState->setText("socket状态:ConnectingState");break;case QAbstractSocket::ConnectedState:labSocketState->setText("socket状态:ConnectedState");break;case QAbstractSocket::BoundState:labSocketState->setText("socket状态:BoundState");break;case QAbstractSocket::ListeningState:labSocketState->setText("socket状态:ListeningState");break;case QAbstractSocket::ClosingState:labSocketState->setText("socket状态:ClosingState");break;default:break;}
}void MainWindow::on_SocketReadyRead()
{QByteArray datagram;datagram.resize(udpSocket->pendingDatagramSize());QHostAddress peerAddr;unsigned short peerPort;udpSocket->readDatagram(datagram.data(), datagram.size(), &peerAddr, &peerPort);QString str = datagram.data();QString peer = "[From " + peerAddr.toString() + ":" + QString::asprintf("%d", peerPort) + "] ";ui->plainTextEdit->appendPlainText(peer  + str);
}void MainWindow::on_actStart_triggered()
{QString IP = ui->comboBox->currentText();groupAddress = QHostAddress(IP);quint16 groupPort = ui->spinBoxBindPort->value();if(udpSocket->bind(QHostAddress::AnyIPv4, groupPort, QUdpSocket::ShareAddress)){udpSocket->joinMulticastGroup(groupAddress);ui->plainTextEdit->appendPlainText("**加入组播成功");ui->plainTextEdit->appendPlainText("**组播IP:" + IP);ui->plainTextEdit->appendPlainText("**组播端口:" + QString::number(groupPort));ui->actStart->setEnabled(false);ui->actStop->setEnabled(true);ui->comboBox->setEnabled(false);}else{ui->plainTextEdit->appendPlainText("**端口绑定失败");}
}void MainWindow::on_actStop_triggered()
{udpSocket->leaveMulticastGroup(groupAddress);udpSocket->abort();ui->actStart->setEnabled(true);ui->actStop->setEnabled(false);ui->comboBox->setEnabled(true);ui->plainTextEdit->appendPlainText("**已退出组播,解除端口绑定");
}void MainWindow::on_actClear_triggered()
{ui->plainTextEdit->clear();
}void MainWindow::on_btnSend_clicked()
{QString targetIP = ui->comboBox->currentText();quint16 targetPort = ui->spinBoxBindPort->value();QHostAddress targetAddr(targetIP);QString msg = ui->lineEdit->text();QByteArray data = msg.toUtf8();udpSocket->writeDatagram(data, targetAddr, targetPort);ui->plainTextEdit->appendPlainText("[out] " + msg);ui->lineEdit->clear();ui->lineEdit->setFocus();
}

在这里插入图片描述

四、HTTP通信

1、相关类

QNetworkRequest,通过一个URL地址发起网络请求,也保存网络请求信息。
QNetworkAccessManager,用于协调网络操作,在QNetworkRequest发起一个网络请求后,负责发送网络请求,创建网络响应。
QNwtworkReply,网络请求的响应。

1、实现基于http协议文件下载

在这里插入图片描述

(1)创建项目

在这里插入图片描述

(2)实现功能

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDir>
#include <QMessageBox>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);
}MainWindow::~MainWindow()
{delete ui;
}#include <QDesktopServices>
void MainWindow::on_finished()
{QFileInfo fileInfo;fileInfo.setFile(downloadFile->fileName());downloadFile->close();delete downloadFile;downloadFile = nullptr;reply->deleteLater();reply = nullptr;if(ui->checkBox->isChecked()){QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.absolutePath()));ui->btnDownload->setEnabled(true);}
}void MainWindow::on_readyRead()
{downloadFile->write(reply->readAll());
}void MainWindow::on_downloadProgress(qint64 readBytes, qint64 totalBytes)
{ui->progressBar->setMaximum(totalBytes);ui->progressBar->setValue(readBytes);
}void MainWindow::on_btnDownload_clicked()
{QString strUrl = ui->lineEditUrl->text();if(strUrl.isEmpty()){QMessageBox::information(this, "error", "请输入正确地址");return;}QUrl newUrl = QUrl::fromUserInput(strUrl);if(!newUrl.isValid()){QMessageBox::information(this, "error",QString::asprintf("无效的URL:%s\n错误信息: %s", strUrl.data(), newUrl.errorString().data()));return;}QString tempDir = ui->lineEditSavePath->text();if(tempDir.isEmpty()){QMessageBox::information(this, "error", "保存路径无效");return;}QString fullFileName = tempDir + newUrl.fileName();if(QFile::exists(fullFileName)){QFile::remove(fullFileName);}downloadFile = new QFile(fullFileName);if(!downloadFile->open(QIODevice::WriteOnly)){QMessageBox::information(this, "error", "文件打开失败:" + fullFileName);return;}ui->btnDownload->setEnabled(false);reply = networkManager.get(QNetworkRequest(newUrl));connect(reply, SIGNAL(finished()), this, SLOT(on_finished()));connect(reply, SIGNAL(readyRead()), this, SLOT(on_readyRead()));connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(on_downloadProgress(qint64, qint64)));
}void MainWindow::on_btnDefaultPath_clicked()
{QString curPath = QDir::currentPath();QDir dir(curPath);QString sub("temp");dir.mkdir(sub);ui->lineEditSavePath->setText(dir.path() + "/" + sub + "/");
}

在这里插入图片描述

五、打包程序

将指定程序打包,将依赖库打包进目录
D:\Qt\Qt5.13.0\5.13.0\mingw73_64\bin\windeployqt.exe E:/XXX/xxx.exe

在这里插入图片描述

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

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

相关文章

【01】openEuler 源码安装 PostgreSQL

openEuler 源码安装 PostgreSQL 部署环境说明Shell 前端软件包管理器基础概念YUM 简介DNF 简介 源码安装 PostgreSQL环境变量&#xff08;env&#xff09;设置临时环境变量设置永久环境变量设置 初始化数据库&#xff08;initdb&#xff09; 数据库基本操作数据库基本配置&…

c++结构体内存对齐

结构体内存对齐 试试运行下面的例子 #include <stdio.h> #include <stdlib.h>using namespace std;struct A{char c;int i; };struct B{char c; int i; double d; };struct C{char c;int i;double d;char c1; };int main(){printf("sizeof(A): %d\n"…

SparkStreaming在实时处理的两个场景示例

简介 Spark Streaming是Apache Spark生态系统中的一个组件&#xff0c;用于实时流式数据处理。它提供了类似于Spark的API&#xff0c;使开发者可以使用相似的编程模型来处理实时数据流。 Spark Streaming的工作原理是将连续的数据流划分成小的批次&#xff0c;并将每个批次作…

适配器模式 详解 设计模式

适配器模式 适配器模式是一种结构型设计模式&#xff0c;其主要作用是解决两个不兼容接口之间的兼容性问题。适配器模式通过引入一个适配器来将一个类的接口转换成客户端所期望的另一个接口&#xff0c;从而让原本由于接口不匹配而无法协同工作的类能够协同工作。 结构 适配…

想要调用淘宝开放平台API,没有申请应用怎么办?

用淘宝自定义API接口可以访问淘宝开放平台API。 custom-自定义API操作 taobao.custom 公共参数 注册账号获取API请求地址 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xf…

Docker与虚拟机比较

在对比Docker和虚拟机前&#xff0c;先简单了解下虚拟化&#xff0c;明确Docker和虚拟机分别对应的虚拟化级别&#xff0c;然后对Docker和虚拟机进行比较。需要注意的是&#xff0c;Docker和虚拟机并没有什么可比性&#xff0c;而是Docker使用的容器技术和虚拟机使用的虚拟化技…

【K8S类型系统】一文梳理 K8S 各类型概念之间的关系(GVK/GVR/Object/Schema/RestMapper)

参考 k8s 官方文档 https://kubernetes.io/zh-cn/docs/reference/https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/ 重点 Kubernetes源码学习-kubernetes基础数据结构 - 知乎 重点 Kubernetes类型系统 | 李乾坤的博客 重点 k8s源码学习-三大核心数…

前端学习第二天-html提升

达标要求 了解列表的分类 熟练掌握列表的用法 熟练掌握表格的结构构成 合并单元格 表单的组成 熟练掌握表单控件分类的使用 1.列表 1.1 无序列表 <ul>&#xff1a;定义无序列表&#xff0c;并且只能包含<li>子元素。 <li>&#xff1a;定义列表项&a…

LZO索引文件失效说明

在hive中创建lzo文件和索引时&#xff0c;进行查询时会出现问题.hive的默认输入格式是开启小文件合并的&#xff0c;会把索引也合并进来。所以要关闭hive小文件合并功能&#xff01;

Matlab:元胞自动机

元胞自动机是一种基于离散空间的动态系统&#xff0c;由许多简单单元按照某些规则进行相互作用和演化而形成的复杂结构。元胞自动机可以用于模拟物理、生物、社会等领域的现象&#xff0c;以及进行优化、图像处理、噪声生成等方面的应用。 例1&#xff1a;生命游戏 nextState…

maven项目报错Cannot resolve plugin org.apache.maven.plugins:maven-war-plugin:2.2

如果IDEA整合maven没有问题&#xff0c;还是报这个错误&#xff0c;很大可能是由于在下载过程中存在网络问题&#xff0c;导致文件下载一半而停止&#xff0c;但是已经在仓库中存在这个文件夹&#xff0c;解决方法是删除文件夹重新下载即可。 删除本地仓库下的\org\apache\mav…

(算法)位运算

常见的位运算符&#xff1a; 给定一个数n判断他的二进制第x位是0还是1 把第x位修改为1 因为是只是修改n的某个位置&#xff0c;所以不应该移动改变n 既然修改为1&#xff0c;那么就要想到 | 运算符 把第x位修改为0 因为修改为0,所以要用&运算符 位图思想 判定字符串…

二维码门楼牌管理系统技术服务的深度解析

文章目录 前言一、标准地址名称的定义与重要性二、二维码门楼牌管理系统的核心技术三、标准地址名称在二维码门楼牌管理中的应用四、二维码门楼牌管理系统的优势与挑战五、展望未来 前言 在数字化浪潮中&#xff0c;二维码门楼牌管理系统以其高效、便捷的特性&#xff0c;正逐…

【一】【算法分析与设计】基础测试

排列式 题目描述 7254是一个不寻常的数&#xff0c;因为它可以表示为7254 39 x 186&#xff0c;这个式子中1~9每个数字正好出现一次 输出所有这样的不同的式子&#xff08;乘数交换被认为是相同的式子&#xff09; 结果小的先输出&#xff1b;结果相同的&#xff0c;较小的乘…

js 实战小案例

实战 时间 js 格式化时间 <script type"text/javascript">function formatDate(date) { let year date.getFullYear(); let month String(date.getMonth() 1).padStart(2, 0); // getMonth() 返回的月份是从0开始的&#xff0c;所以要加1&#xff0c;并…

【go从入门到精通】go包,内置类型和初始化顺序

大家好&#xff0c;这是我给大家准备的新的一期专栏&#xff0c;专门讲golang&#xff0c;从入门到精通各种框架和中间件&#xff0c;工具类库&#xff0c;希望对go有兴趣的同学可以订阅此专栏。 go基础 。 Go文件名&#xff1a; 所有的go源码都是以 ".go" 结尾&…

Mamba 环境安装:causal-conv1d和mamba-ssm报错解决办法

问题描述&#xff1a; 在执行命令 pip install causal_conv1d 和 mamba_ssm 出错&#xff1a; 解决方案&#xff1a; 1、使用网友配置好的Docker环境&#xff0c;参考&#xff1a;解决causal_conv1d和mamba_ssm无法安装 -&#xff1e; 直接使用Mamba基础环境docker镜像 DockH…

java实现图片转pdf,并通过流的方式进行下载(前后端分离)

首先需要导入相关依赖&#xff0c;由于具体依赖本人也不是记得很清楚了&#xff0c;所以简短的说一下。 iText&#xff1a;PDF 操作库&#xff0c;用于创建和操作 PDF 文件。可通过 Maven 或 Gradle 引入 iText 依赖。 MultipartFile&#xff1a;Spring 框架中处理文件上传的类…

一台工控机的能量

使用Docker搭建EPICS的IOC记录 Zstack EPICS Archiver在小课题组的使用经验 以前电子枪调试&#xff0c;用一台工控机跑起束测后台&#xff0c;这次新光源用的电子枪加工回来又是测试&#xff0c;又是用一台工控机做起重复的事&#xff0c;不过生命在于折腾&#xff0c;重复的…

stm32——hal库学习笔记(IIC)

一、IIC总线协议介绍&#xff08;掌握&#xff09; 二、AT24C02介绍&#xff08;了解&#xff09; 三、AT24C02读写时序&#xff08;掌握&#xff09; 四、AT24C02驱动步骤&#xff08;掌握&#xff09; 五、编程实战&#xff08;掌握&#xff09; myiic.c #include "./B…