(轉)Qt Model/View 學習筆記 (六)——在views中選擇數據項


在views中選擇數據項

概念

用於新的view類中的選擇模型比Qt3中的模型有了很大的改進。它為基於model/view架構的選擇提供了更為全面的描述。盡管對提供了的views來說,負責操縱選擇的標准類已經足以應付,但是你也可以創建特定的選擇模型來滿足你特殊的需求。

關於在view被選擇的數據項的信息保持在QItemSelectionModel類的實例中。它也為每個獨立的model中的數據項維護model indexes信息,與任何views都關聯關系。既然一個model可用於多個views,那么在多個views之間共享選擇信息也是可以做到的,這使得多個views可以以一致的方式進行顯示。

選擇由多個選擇范圍組成。通過僅僅記錄開始model indexes與結束model indexes,最大化地記錄了可以選擇的范圍。非連續選擇數據項由多個選擇范圍來描述。選擇模型記錄model indexes的集合來描述一個選擇。最近選擇的數據項被稱為current selection。應用程序可以通過使用某種類型的選擇命令來修改選擇的效果。

在進行選擇操作時,可以把QItemSelectionModel看成是model中所有數據項選擇狀態的一個記錄。一旦建立一個選擇模型,所有項的集合都可以選擇,撤消選擇,或者選擇狀態進行切換而不需要知道哪個數據項是否已經被選擇過。所有被選擇的項的indexes在任何時候都可以得到,通過信號槽機制可以通知別的組件發生的變化。

使用選擇模型

標准view類提供了缺省的選擇模型,它們可以在大次數程序中使用。一個view中的選擇模型可以通過調用view的函數selectionModel()取得,也可以通過setSelectionModel()在多個views之間共享選擇模型,因此總的來說構建一個新的模型一般情況不太必要。

通過給QItemSelection指定一個model,一對model indexes,可以創建一個選擇。indexes的用法依賴於給定的model,這兩個indexes被解釋成選擇的區塊中的左上角項和右下角項。model中的項的選擇服從於選擇模型。

選擇項

構建一個table model ,它有32個項,用一個table view進行顯示:

     TableModel *model = new TableModel(8, 4, &app);

     QTableView *table = new QTableView(0);

     table->setModel(model);

     QItemSelectionModel *selectionModel = table->selectionModel();

     QModelIndex topLeft;

     QModelIndex bottomRight;

     topLeft = model->index(0, 0, QModelIndex());

     bottomRight = model->index(5, 2, QModelIndex());

    

      QItemSelection selection(topLeft, bottomRight);

     selectionModel->select(selection, QItemSelectionModel::Select);

結果如下:

QTreeView - zhengjiu_520 - !snows snowy world!

讀取選擇狀態

存儲在選擇模型中indexes可以用selectionIndexes()函數來讀取。它返回一個未排序的model indexes列表,我們可以遍歷它,如果我們知道他們關聯於哪個model的話。

    QModelIndexList indexes = selectionModel->selectedIndexes();

     QModelIndex index;

     foreach(index, indexes) {

         QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());

         model->setData(index, text);

     }

選擇模型在選擇發生變化時會發出信號。這用於通知別的組件包括整體與當前焦點項所發生的變化。我們可以連接selectionChanged()信號到一個槽,檢查當信號產生時哪些項被選擇或被取消選擇。這個槽被調用時帶有兩個參數,它們都是QItemSelection對象,一個包含新被選擇的項,另一個包含新近被取消選擇的項。下面的代碼演示了給新選擇的項添加數據內容,新近被取消選擇的項的內容被清空。

void MainWindow::updateSelection(const QItemSelection &selected,

     const QItemSelection &deselected)

 {

     QModelIndex index;

     QModelIndexList items = selected.indexes();

     foreach (index, items) {

         QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());

         model->setData(index, text);

     }

     items = deselected.indexes();

     foreach (index, items)

      model->setData(index, "");

 }

也可以通過響應currentChanged()信號來跟蹤當前焦點項.對應的槽就有兩個接收參數,一個表示之前的焦點,另一個表示當前的焦點。

void MainWindow::changeCurrent(const QModelIndex &current,

     const QModelIndex &previous)

 {

     statusBar()->showMessage(

         tr("Moved from (%1,%2) to (%3,%4)")

             .arg(previous.row()).arg(previous.column())

             .arg(current.row()).arg(current.column()));

 }

更新選擇

選擇指令是通過選擇標志提供的,它被定義在QItemSelectionModel::SelectionFlag中。常用的有Select標記,Toggle標記,Deselect標記,Current標記,Clear標記,其意義一目了然。沿上面例子的結果執行以下代碼:

     QItemSelection toggleSelection;

     topLeft = model->index(2, 1, QModelIndex());

     bottomRight = model->index(7, 3, QModelIndex());

     toggleSelection.select(topLeft, bottomRight);

     selectionModel->select(toggleSelection, QItemSelectionModel::Toggle);

結果如下:

QTreeView - zhengjiu_520 - !snows snowy world!

缺省情況下,選擇指令只針對單個項(由model indexes指定)。然而,選擇指令可以通過與另外標記的結合來改變整行和整列。舉例來說,假如你只使用一個index來調用select(),但是用Select標記與Rows標記的組合,那么包括那個項的整行都將被選擇。看以下示例:

     QItemSelection columnSelection;

     topLeft = model->index(0, 1, QModelIndex());

     bottomRight = model->index(0, 2, QModelIndex());

     columnSelection.select(topLeft, bottomRight);

     selectionModel->select(columnSelection,

     QItemSelectionModel::Select | QItemSelectionModel::Columns);

     QItemSelection rowSelection;

     topLeft = model->index(0, 0, QModelIndex());

     bottomRight = model->index(1, 0, QModelIndex());

     rowSelection.select(topLeft, bottomRight);

     selectionModel->select(rowSelection,

     QItemSelectionModel::Select | QItemSelectionModel::Rows);

結果如下

QTreeView - zhengjiu_520 - !snows snowy world!

選擇模型中所有項

為了選擇model中的所有項,必須先得創建一個選擇,它包括當前層次上的所有項:

     QModelIndex topLeft = model->index(0, 0, parent);

     QModelIndex bottomRight = model->index(model->rowCount(parent)-1,

      model->columnCount(parent)-1, parent);

    QItemSelection selection(topLeft, bottomRight);

     selectionModel->select(selection, QItemSelectionModel::Select);

頂級index可以這樣:

QModelIndex parent = QModelIndex();

對具有層次結構的model來說,可以使用hasChildren()函數來決定給定項是否是其它項的父項。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM