[Qt教程] 第34篇 网络(四)FTP(二)
生活随笔
收集整理的這篇文章主要介紹了
[Qt教程] 第34篇 网络(四)FTP(二)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[Qt教程]?第34篇 網絡(四)FTP(二)
??|?查看: 315|?回復: 9| FTP(二) 版權聲明 該文章原創于作者yafeilinux,轉載請注明出處! 導語 前面講述了一個最簡單的FTP客戶端程序的編寫,這一節我們將這個程序進行擴展,使其可以瀏覽并能下載服務器上的所有文件。 環境:Windows Xp + Qt 4.8.5+QtCreator 2.8.0 目錄 一、修改界面 二、功能實現 正文 一、修改界面 我們刪除了TextBrowser?,加入了幾個Label?,Line Edit?,Push Button部件,一個Tree Widget及一個Progress Bar部件。然后我們對其中幾個部件做如下更改。 (1)將“FTP服務器”標簽后的Line Edit的objectName屬性改為“ftpServerLineEdit”,其text?屬性改為“ftp.qt-project.org”。 (2)將“用戶名”標簽后的Line Edit的objectName屬性改為“userNameLineEdit”,其text屬性改為“anonymous”,將其toolTip屬性改為“默認用戶名請使用:anonymous?,此時密碼任意。” (3)將“密碼”標簽后的Line Edit的objectName屬性改為“passWordLineEdit”,其text屬性改為“123456”,將其echoMode屬性改為“Password”。 (4)將“連接”按鈕的objectName屬性改為“connectButton”。 (5)將“返回上一級目錄”按鈕的objectName屬性改為“cdToParentButton”。 (6)將“下載”按鈕的objectName屬性改為“downloadButton”。 (7)將Tree Widget的objectName屬性改為“fileList”,然后在Tree Widget部件上單擊鼠標右鍵,選擇Edit Items菜單,添加列屬性如下。 最終界面如圖所示: 下面我們的程序中,就是實現在用戶填寫完相關信息后,按下“連接”按鈕,就可以連接到FTP服務器,并在TreeWidget中顯示服務器上的所有文件,我們可以按下“下載”按鈕來下載選中的文件,并使用進度條顯示下載進度。 二、功能實現 1.更改widget.h文件。 (1)添加頭文件#include <QtGui> (2)在private中添加變量: QHash<QString,?bool>?isDirectory;?//用來存儲一個路徑是否為目錄的信息 QString?currentPath;?//用來存儲現在的路徑 QFile?*file; (3)添加槽: private slots: void?on_downloadButton_clicked(); void?on_cdToParentButton_clicked(); void?on_connectButton_clicked(); void?ftpCommandFinished(int,bool); void?ftpCommandStarted(int); void?updateDataTransferProgress(qint64,qint64?);//更新進度條 //將服務器上的文件添加到Tree?Widget中 void?addToList(const?QUrlInfo?&urlInfo); void?processItem(QTreeWidgetItem*,int);//雙擊一個目錄時顯示其內容 2.更改widget.cpp的內容。 (1)實現“連接”按鈕的單擊事件槽。 void?Widget::on_connectButton_clicked()? ?//連接按鈕 { ? ??ui->fileList->clear(); ? ??currentPath.clear(); ? ??isDirectory.clear(); ? ? ? ??ftp?=?new?QFtp(this); ? ??connect(ftp,SIGNAL(commandStarted(int)), this,SLOT(ftpCommandStarted(int))); ? ??connect(ftp,SIGNAL(commandFinished(int,bool)), ? ?? ?? ???this,SLOT(ftpCommandFinished(int,bool))); ? ??connect(ftp,SIGNAL(listInfo(QUrlInfo)), this,SLOT(addToList(QUrlInfo))); ? ??connect(ftp,SIGNAL(dataTransferProgress(qint64,qint64)), ? ?? ?? ???this,SLOT(updateDataTransferProgress(qint64,qint64))); ? ? ? ??QString?ftpServer?=?ui->ftpServerLineEdit->text(); ? ??QString?userName?=?ui->userNameLineEdit->text(); ? ??QString?passWord?=?ui->passWordLineEdit->text(); ? ??ftp->connectToHost(ftpServer,21);?//連接到服務器,默認端口號是21 ? ??ftp->login(userName,passWord);? ?//登錄 } 我們在“連接”按鈕的單擊事件槽函數中新建了ftp對象,然后關聯了相關的信號和槽。這里的listInfo()信號由ftp->list()函數發射,它將在登錄命令完成時調用,下面我們提到。而dataTransferProgress()信號在數據傳輸時自動發射。最后我們從界面上獲得服務器地址,用戶名和密碼等信息,并以它們為參數執行連接和登錄命令。 (2)更改ftpCommandFinished()函數。 我們在相應位置做更改。 首先,在登錄命令完成時,我們調用list()函數: ui->label->setText(tr("登錄成功")); ftp->list();? ?//發射listInfo()信號,顯示文件列表? ? 然后,在下載命令完成時,我們使下載按鈕可用,并關閉打開的文件。 ui->label->setText(tr("已經完成下載")); ui->downloadButton->setEnabled(true); file->close();? ??? delete?file; 最后再添加一個if語句,處理list命令完成時的情況: if?(ftp->currentCommand()?==?QFtp::List){ ? ?? ??if?(isDirectory.isEmpty()) ? ?? ??{?//如果目錄為空,顯示“empty” ? ?? ?? ???ui->fileList->addTopLevelItem( ? ?? ?? ?? ?? ?? ?new?QTreeWidgetItem(QStringList()<<?tr("<empty>"))); ? ?? ?? ???ui->fileList->setEnabled(false); ? ?? ?? ???ui->label->setText(tr("該目錄為空")); ? ?? ??} } 我們在list命令完成時,判斷文件列表是否為空,如果為空,就讓Tree Widget不可用,并顯示“empty”條目。 (3)添加文件列表函數的內容如下。 void?Widget::addToList(const?QUrlInfo?&urlInfo)??//添加文件列表 { ? ??QTreeWidgetItem?*item?=?new?QTreeWidgetItem; ? ??item->setText(0,?urlInfo.name()); ? ??item->setText(1,?QString::number(urlInfo.size())); ? ??item->setText(2,?urlInfo.owner()); ? ??item->setText(3,?urlInfo.group()); ? ??item->setText(4,?urlInfo.lastModified().toString("MMM?dd?yyyy")); ? ? ? ??QPixmap?pixmap(urlInfo.isDir()???"../myFtp2/dir.png"?:?"../myFtp2/file.png"); ? ??item->setIcon(0,?pixmap); ? ? ? ??isDirectory[urlInfo.name()]?=?urlInfo.isDir(); ? ??//存儲該路徑是否為目錄的信息 ? ??ui->fileList->addTopLevelItem(item); ? ??if?(!ui->fileList->currentItem())?{ ? ?? ??ui->fileList->setCurrentItem(ui->fileList->topLevelItem(0)); ? ?? ??ui->fileList->setEnabled(true); ? ??} } 當ftp->list()函數執行時會發射listInfo()信號,此時就會執行addToList()函數,在這里我們將文件信息顯示在Tree Widget上,并在isDirectory中存儲該文件的路徑及其是否為目錄的信息。為了使文件與目錄進行區分,我們使用了不同的圖標file.png和dir.png來表示它們,這兩個圖標放在了工程文件夾中。 (4)將構造函數的內容更改如下。 { ? ??ui->setupUi(this); ? ??ui->progressBar->setValue(0); ? ??//鼠標雙擊列表中的目錄時,我們進入該目錄 ? ??connect(ui->fileList,SIGNAL(itemActivated(QTreeWidgetItem*,int)), ? ?? ?? ???this,SLOT(processItem(QTreeWidgetItem*,int))); } 這里我們只是讓進度條的值為0,然后關聯了Tree Widget的一個信號itemActivated()。當鼠標雙擊一個條目時,發射該信號,我們在槽函數中判斷該條目是否為目錄,如果是則進入該目錄。 (5)processItem()函數的實現如下。 void?Widget::processItem(QTreeWidgetItem*?item,int)??//打開一個目錄 { ? ??QString?name?=?item->text(0); ? ??if?(isDirectory.value(name))?{??//如果這個文件是個目錄,則打開 ? ?? ??ui->fileList->clear(); ? ?? ??isDirectory.clear(); ? ?? ??currentPath?+=?'/'; ? ?? ??currentPath?+=?name; ? ?? ??ftp->cd(name); ? ?? ??ftp->list(); ? ?? ??ui->cdToParentButton->setEnabled(true); ? ??} } (6)“返回上一級目錄”按鈕的單擊事件槽函數如下。 void?Widget::on_cdToParentButton_clicked()??//返回上級目錄按鈕 { ? ??ui->fileList->clear(); ? ??isDirectory.clear(); ? ??currentPath?=?currentPath.left(currentPath.lastIndexOf('/')); ? ??if?(currentPath.isEmpty())?{ ? ?? ??ui->cdToParentButton->setEnabled(false); ? ?? ??ftp->cd("/"); ? ??}?else?{ ? ?? ??ftp->cd(currentPath); ? ??} ? ??ftp->list(); } 在返回上一級目錄時,我們取當前路徑的最后一個“/”之前的部分,如果此時路徑為空了,我們就讓“返回上一級目錄”按鈕不可用。 (7)“下載”按鈕單擊事件槽函數如下。 void?Widget::on_downloadButton_clicked()??//下載按鈕 { ? ??QString?fileName?=?ui->fileList->currentItem()->text(0); ? ??file?=?new?QFile(fileName); ? ??if?(!file->open(QIODevice::WriteOnly)) ? ??{ ? ?? ??delete?file; ? ?? ??return; } //下載按鈕不可用,等下載完成后才可用 ui->downloadButton->setEnabled(false);? ? ftp->get(ui->fileList->currentItem()->text(0), file); } 在這里我們獲取了當前項目的文件名,然后新建文件,使用get()命令下載服務器上的文件到我們新建的文件中。 (8)更新進度條函數內容如下。 void?Widget::updateDataTransferProgress(?//進度條 ? ?? ?? ?? ?? ?? ?qint64?readBytes,qint64?totalBytes) { ? ??ui->progressBar->setMaximum(totalBytes); ? ??ui->progressBar->setValue(readBytes); } 3.流程說明。 整個程序的流程就和我們實現函數的順序一樣。用戶在界面上輸入服務器的相關信息,然后我們利用這些信息進行連接并登錄服務器,等登錄服務器成功時,我們列出服務器上所有的文件。對于一個目錄,我們可以進入其中,并返回上一級目錄,我們可以下載文件,并顯示下載的進度。 對于ftp的操作,全部由那些命令和信號來完成,我們只需要調用相應的命令,并在其發出信號時,進行對應的處理就可以了。而對于文件的顯示,則是視圖部分的知識了。 4.運行程序,效果如下圖所示。 ? 結語 最后需要說明的是,因為為了更好的講解知識,使得程序簡單化,所以我們省去了很多細節上的處理,如果需要,你可以自己添加。比如斷開連接和取消下載,你都可以使用 ftp->abort()函數。你也可以參考Qt自帶的Ftp Example例子。對于其他操作,比如上傳等,你可以根據需要添加。 ? ?? ?FTP的相關編程就講到到這里。 涉及到的源碼下載:??myFtp2.rar?? |
總結
以上是生活随笔為你收集整理的[Qt教程] 第34篇 网络(四)FTP(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Qt教程] 第33篇 网络(三)FTP
- 下一篇: [Qt教程] 第35篇 网络(五)获取本