Qt Model View 預定義模型(二)
- 2019 年 10 月 5 日
- 筆記
上次和大家分享的是在不區分模型和視圖帶來方便的情況下,可以直接使用Qt項視圖中簡便的子類,如QListWidget、QTableWidget、QTreeWidget等。本次和大家分享下如何使用Qt預定義的一些模型。
首先了解下幾種預定義模型:
QStringListModel |
用於存儲QString項的簡單列表 |
---|---|
QStandardItemModel |
管理更複雜的項目樹結構,每個項目都可以包含任意數據 |
QFileSystemModel |
提供有關本地文件系統中的文件和目錄的資訊 |
QSqlQueryModel |
用於使用模型/視圖約定訪問資料庫。 |
QSqlTableModel |
|
QSqlRelationalTableModel |
我自己剛開始看的時候,看到這裡也是挺蒙圈的。沒有直接應用的項目,看了之後印象不深,也沒有自己重新總結,過後就忘得差不多了。後來比較直觀的是在項目中用到了QListView做了一個簡單的文件顯示系統,結合QFile可以新建文件、刪除文件、編輯文件等,算是簡單的使用了一次Model/View。
這次要給大家展示的是對於同一個數據源,使用相同的Model讀取數據,通過將該模型註冊到不同的View中,所展現的效果。以及對於同一個數據源使用不同的Model,註冊到View中的效果。聽著會有一些繞,看程式時候會有比較直觀的感受。
程式環境:ubuntu Qt5.5.1
Ui結構是Design的tabWidget中分別有listView和tableView兩個View,這兩個View使用的是同一個數據源和相同的Model——QFileSystemModel。還有一個是通過程式碼insert到tabWidget中的treeView,它與listView和tableView使用的是同一個數據源,但是使用的Model是QDirModel。這樣我們對Model/View就有了一個相對直觀的了解。Model不關心數據源,數據源可以是資料庫或是其他形式,根據數據的特點選擇合適的Model,最後再根據要展現給用戶的形式選取一個View。按照上述的結構,也就達到了UI、業務邏輯和數據分離的效果了。
mp_fileSystemModel = new QFileSystemModel; mp_fileSystemModel->setRootPath(QDir::currentPath());、 void Widget::on_pbn_tableView_clicked() { ui->tableView->setModel(mp_fileSystemModel); ui->tableView->setRootIndex(mp_fileSystemModel->index(QDir::currentPath())); }
以上就完成了預定義文件系統模型和listView的設置,顯示效果如下:

如果選取了一個文件,可以獲取當前文件的索引。注意下,這裡面是無法點開文件夾的。
接下來看下tableView的顯示效果:

以上就是使用同一個數據源,使用不同View的顯示效果。接下來的treeView的設置及顯示效果。
mp_dirModel = new QDirModel; //可編輯 mp_dirModel->setReadOnly(false); //初始排序屬性 mp_dirModel->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name); mp_treeView = new QTreeView(this); mp_treeView->setModel(mp_dirModel); mp_treeView->setRootIndex(mp_dirModel->index(QDir::currentPath())); mp_treeView->header()->setStretchLastSection(true); mp_treeView->header()->setSortIndicator(0, Qt::AscendingOrder); mp_treeView->header()->setSortIndicatorShown(true); mp_treeView->header()->setSectionsClickable(true); 設置treeView的模型以及treeView的View屬性。 void treeView::slot_createDirectory() { QModelIndex index = mp_treeView->currentIndex(); if (!index.isValid()) return; QString dirName = QInputDialog::getText(this, tr("Create Directory"), tr("Directory name")); if (!dirName.isEmpty()) { if (!mp_dirModel->mkdir(index, dirName).isValid()) QMessageBox::information(this, tr("Create Directory"), tr("Failed to create the directory")); } }
添加一個新的目錄。效果如圖:
