在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ C/ QDirModel
Qt 容器和算法拾遺
自定義 model 之一
反走樣
Hello, world!
Qt 容器類之關(guān)聯(lián)存儲(chǔ)容器
QStringListModel
拖放技術(shù)之一
狀態(tài)欄
QTreeWidget
拖放技術(shù)之二
通用算法
event()
Qt 學(xué)習(xí)之路(18): Qt 標(biāo)準(zhǔn)對(duì)話框之 QInputDialog
Qt 容器類之遍歷器和隱式數(shù)據(jù)共享
QListWidget
Meta-Object 系統(tǒng)
事件接收與忽略
Qt 學(xué)習(xí)之路(tip): parent 參數(shù)
Qt 標(biāo)準(zhǔn)對(duì)話框之 QColorDialog
QPainter(續(xù))
國(guó)際化(下)
漸變填充
自定義委托
創(chuàng)建 shared library
model-view 架構(gòu)
Graphics View Framework
自定義拖放數(shù)據(jù)對(duì)象
QSortFilterProxyModel
國(guó)際化(上)
組件布局
自定義 Model 之三
事件過濾器
QDirModel
Hello, world!(續(xù))
Qt 標(biāo)準(zhǔn)對(duì)話框之 QFileDialog
自定義 model 之二
深入了解信號(hào)槽
坐標(biāo)變換
剪貼板操作
QTableWidget
QByteArray 和 QVariant
創(chuàng)建一個(gè)對(duì)話框(下)
Qt 學(xué)習(xí)之路(32): 一個(gè)簡(jiǎn)易畫板的實(shí)現(xiàn)(Graphics View)
文本文件讀寫
自定義事件
編寫跨平臺(tái)的程序
MainWindow
初探信號(hào)槽
Qt 學(xué)習(xí)之路(17): Qt 標(biāo)準(zhǔn)對(duì)話框之 QMessageBox
繪圖設(shè)備
菜單和工具條(續(xù))
二進(jìn)制文件讀寫
QString
事件(event)
菜單和工具條
QPainter
Qt 容器類之順序存儲(chǔ)容器
進(jìn)程間交互
API 文檔的使用
創(chuàng)建一個(gè)對(duì)話框(上)
一個(gè)簡(jiǎn)易畫板的實(shí)現(xiàn)(QWidget)

QDirModel

今天我們來看一個(gè)很有用的 model:QDirModel。這個(gè) model 允許我們?cè)?view 中顯示操作系統(tǒng)的目錄結(jié)構(gòu)。這次讓我們先來看看運(yùn)行結(jié)果:

http://wiki.jikexueyuan.com/project/learn-road-qt/images/73.png" alt="" />

這個(gè)界面很熟悉吧?不過這可不是由 QFileDialog 打開的哦,這是我們自己實(shí)現(xiàn)的。而提供這種實(shí)現(xiàn)支持的,就是 QDirModel 和 QTreeView。我們來看一下代碼。

mytreeview.h


#ifndef MYLISTVIEW_H 
#define MYLISTVIEW_H 

#include <QtGui> 

class MyTreeView : public QWidget 
{ 
        Q_OBJECT 
public: 
        MyTreeView(); 

private: 
        QDirModel *model; 
        QTreeView *treeView; 

private slots: 
        void mkdir(); 
        void rm(); 
}; 

#endif // MYLISTVIEW_H

mytreeview.cpp


#include "mylistview.h" 

MyTreeView::MyTreeView() 
{ 
        model = new QDirModel; 
        model->setReadOnly(false); 
        model->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name); 

        treeView = new QTreeView; 
        treeView->setModel(model); 
        treeView->header()->setStretchLastSection(true); 
        treeView->header()->setSortIndicator(0, Qt::AscendingOrder); 
        treeView->header()->setSortIndicatorShown(true); 
        treeView->header()->setClickable(true); 

        QModelIndex index = model->index(QDir::currentPath()); 
        treeView->expand(index); 
        treeView->scrollTo(index); 
        treeView->resizeColumnToContents(0); 

        QHBoxLayout *btnLayout = new QHBoxLayout; 
        QPushButton *createBtn = new QPushButton(tr("Create Directory...")); 
        QPushButton *delBtn = new QPushButton(tr("Remove")); 
        btnLayout->addWidget(createBtn); 
        btnLayout->addWidget(delBtn); 
        QVBoxLayout *mainLayout = new QVBoxLayout(this); 
        mainLayout->addWidget(treeView); 
        mainLayout->addLayout(btnLayout); 
        this->setLayout(mainLayout); 

        connect(createBtn, SIGNAL(clicked()), this, SLOT(mkdir())); 
        connect(delBtn, SIGNAL(clicked()), this, SLOT(rm())); 
} 

void MyTreeView::mkdir() 
{ 
        QModelIndex index = treeView->currentIndex(); 
        if (!index.isValid()) { 
                return; 
        } 
        QString dirName = QInputDialog::getText(this, 
                                                                                        tr("Create Directory"), 
                                                                                        tr("Directory name")); 
        if (!dirName.isEmpty()) { 
                if (!model->mkdir(index, dirName).isValid()) { 
                        QMessageBox::information(this, 
                                                                         tr("Create Directory"), 
                                                                         tr("Failed to create the directory")); 
                } 
        } 
} 

void MyTreeView::rm() 
{ 
        QModelIndex index = treeView->currentIndex(); 
        if (!index.isValid()) { 
                return; 
        } 
        bool ok; 
        if (model->fileInfo(index).isDir()) { 
                ok = model->rmdir(index); 
        } else { 
                ok = model->remove(index); 
        } 
        if (!ok) { 
                QMessageBox::information(this, 
                                                                 tr("Remove"), 
                                                                 tr("Failed to remove %1").arg(model->fileName(index))); 
        } 
} 

構(gòu)造函數(shù)中,首先我們創(chuàng)建了 QDirModel 的一個(gè)對(duì)象,并且設(shè)置 ReadOnly 為 false,也就是說我們可以對(duì)其進(jìn)行修改。而下一個(gè) setSorting()函數(shù)是對(duì)其進(jìn)行排序,排序的依據(jù)也很清楚:文件夾優(yōu)先(QDir::DirsFirst),忽略大小寫(QDir::IgnoreCase),而且是根據(jù)名字排序(QDir::Name)。更多的規(guī)則組合可以參見 API 文檔了。

然后我們創(chuàng)建一個(gè) QTreeView 實(shí)例,并且把 model 設(shè)置為剛剛的 QDirModel 實(shí)例。然后我們開始設(shè)置 QTreeView 的相關(guān)屬性。首先把 stretchLastSection 設(shè)置為 true。如果把這個(gè)屬性設(shè)置為true,就是說,當(dāng) QTreeView 的寬度大于所有列寬之和時(shí),最后一列的寬度自動(dòng)擴(kuò)展以充滿最后的邊界;否則就讓最后一列的寬度保持原始大小。第二個(gè) setSortIndicator()函數(shù)是設(shè)置哪一列進(jìn)行排序。由于我們前面設(shè)置了 model 是按照名字排序,所以我們這個(gè)傳遞的第一個(gè)參數(shù)是0,也就是第1列。setSortIndicatorShown()函數(shù)設(shè)置顯示列頭上面的排序小箭頭。setClickable(true)則允許鼠標(biāo)點(diǎn)擊列頭。這樣,我們的 QTreeView 就設(shè)置完畢了。最后,我們通過 QDir::currentPath()獲取當(dāng)前 exe 文件運(yùn)行時(shí)路徑,并把這個(gè)路徑當(dāng)成程序啟動(dòng)時(shí)顯示的路徑。expand()函數(shù)即展開這一路徑;scrollTo()函數(shù)是把視圖的視口滾動(dòng)到這個(gè)路徑的位置;resizeColumnToContents()是要求把列頭適應(yīng)內(nèi)容的寬度,也就是不產(chǎn)生...符號(hào)。這樣,我們就通過一系列的參數(shù)設(shè)置好了 QTreeView,讓它能夠?yàn)槲覀冋故灸夸浗Y(jié)構(gòu)。

至于后面的兩個(gè) slot,其實(shí)并不能理解。第一個(gè) mkdir()函數(shù)就是創(chuàng)建一個(gè)文件夾。


void MyTreeView::mkdir() 
{ 
        QModelIndex index = treeView->currentIndex(); 
        if (!index.isValid()) { 
                return; 
        } 
        QString dirName = QInputDialog::getText(this, 
                                                                                        tr("Create Directory"), 
                                                                                        tr("Directory name")); 
        if (!dirName.isEmpty()) { 
                if (!model->mkdir(index, dirName).isValid()) { 
                        QMessageBox::information(this, 
                                                                         tr("Create Directory"), 
                                                                         tr("Failed to create the directory")); 
                } 
        } 
}

正如它的代碼所示,首先獲取選擇的目錄。后面這個(gè) isValid()的判斷很重要,因?yàn)槟J(rèn)情況下是沒有目錄被選擇的,此時(shí)這個(gè)路徑是非法的,為了避免程序出現(xiàn)異常,必須要有這一步判斷。然后會(huì)彈出對(duì)話框詢問新的文件夾名字,如果創(chuàng)建失敗會(huì)有提示,否則就是創(chuàng)建成功。這時(shí)候你就可以到硬盤上的實(shí)際位置看看啦!

刪除目錄的代碼也很類似:


void MyTreeView::rm() 
{ 
        QModelIndex index = treeView->currentIndex(); 
        if (!index.isValid()) { 
                return; 
        } 
        bool ok; 
        if (model->fileInfo(index).isDir()) { 
                ok = model->rmdir(index); 
        } else { 
                ok = model->remove(index); 
        } 
        if (!ok) { 
                QMessageBox::information(this, 
                                                                 tr("Remove"), 
                                                                 tr("Failed to remove %1").arg(model->fileName(index))); 
        } 
}

同樣需要實(shí)現(xiàn)檢測(cè)路徑是否合法。另外需要注意的是,目錄和文件的刪除不是一個(gè)函數(shù),需要調(diào)用 isDir()函數(shù)檢測(cè)。這一步在代碼中有很清楚的描述,這里就不再贅述了。

注意,QDirModel 在最新版 Qt 中已經(jīng)不建議使用了。文檔中說使用 QFileSystemModel 代替。由于這兩者的函數(shù)幾乎一樣,所以就沒有對(duì)代碼進(jìn)行修改。與 QDirModel 不同的是,QFileSystemModel會(huì)啟動(dòng)自己的線程進(jìn)行文件夾的掃描,因此不會(huì)發(fā)生因掃描文件夾而導(dǎo)致的主線程阻塞的現(xiàn)象。另外,無論 QDirModel 還是 QFileSystemModel 都會(huì)對(duì) model 結(jié)果進(jìn)行緩存,如果你要立即刷新結(jié)果,前者提供了 refresh()函數(shù),而后者會(huì)通知 QFileSystemWatcher 類。

本文出自 “豆子空間” 博客,請(qǐng)務(wù)必保留此出處 http://devbean.blog.51cto.com/448512/193918