一、主機信息
1、主機信息接口
- QHostInfo:獲取主機名稱和IP地址
- QNetWorkInterface:獲取主機的所有網絡接口,包括子網掩碼和廣播地址等
(1)使用
項目添加模塊
QT += network
2、實現程序

(1)創建項目,基于QDialog

(2)實現功能
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;
};
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)實現服務器功能
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;
};
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)實現功能
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;
};
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)實現功能
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)實現功能
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)實現功能
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);
}MainWindow::~MainWindow()
{delete ui;
}
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
