處理專案檢視中的選擇

a15322910600發表於2020-12-15

概念

項檢視類中使用的選擇模型提供基於模型/檢視體系結構的工具的選擇的一般描述。儘管用於操作選擇的標準類足以滿足所提供的專案檢視,但選擇模型允許您建立專門的選擇模型,以滿足您自己的專案模型和檢視的要求。

有關檢視中所選項的資訊儲存在QItemSlectModel 類的例項中。這將維護單個模型中項的模型索引,並且獨立於任何檢視。由於模型上可以有許多檢視,因此可以在檢視之間共享選擇,從而允許應用程式以一致的方式顯示多個檢視。

選擇由選擇範圍組成。通過只記錄所選專案的每個範圍的開始和結束模型索引,這些方法有效地維護關於大量專案選擇的資訊。專案的非連續選擇是通過使用多個選擇範圍來描述選擇來構造的。

選擇應用於選擇模型所包含的模型索引集合。最近選擇的應用專案稱為當前選擇。即使在應用了此選擇之後,也可以通過使用某些型別的選擇命令來修改此選擇的效果。

當前項和選定項

在檢視中,始終存在當前項和選定項 - 兩個獨立狀態。項可以是當前專案,並同時選中。檢視負責確保始終存在當前項,例如,鍵盤導航需要當前項。

下表說明當前項和選定項之間的差異。

當前專案選定專案
只能有一個當前項可以有多個選定項
通過鍵導航或滑鼠按鈕單擊更改當前項當使用者與項互動時,根據多個預定義模式(例如,單個選擇、多個選擇等)設定或取消設定項的選定狀態
如果按下編輯鍵F2,或雙擊專案(前提是啟用編輯),則將編輯當前專案當前項可以與錨點一起使用,以指定應選擇或取消選擇的範圍(或兩者的組合)。
當前項由焦點矩形指示所選項使用選擇矩形進行指示。

在操作選擇時,將QItemSelectionModel看作一個專案模型中所有專案的選擇狀態的記錄通常是有幫助的。
設定選擇模型後,可以選擇、取消選擇項集合,也可以切換其選擇狀態,而無需知道已選擇哪些項。可隨時檢索所有選定項的索引,還可以通過訊號和插槽機制通知其他元件對選擇模型進行更改。

使用選擇模型

標準檢視類提供可用於大多數應用程式的預設選擇模型。可以使用檢視的 selectionModel()函式獲取屬於一個檢視的選擇模型,並且在許多檢視之間與setSelectionModel() 共享,因此通常不需要構建新的選擇模型。

通過指定模型和QItemSelection的一對模型索引來建立選擇。它使用索引來引用給定模型中的項,並將它們解釋為選定項塊中的左上和右下項。若要將選擇應用於模型中的專案,則需要將選擇提交給選擇模型;這可以通過多種方式實現,每一種方式都對選擇模型中已經出現的選擇產生不同的影響。

選擇專案:
構建一個自定義表模型的例項,並開啟其資料的表檢視

	QStandardItemModel model(10,10);
    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);

讀取選擇狀態:

儲存在選擇模型中的模型索引可以使用selectedIndexes()函式讀取。這將返回一個未排序的模型索引列表,我們可以遍歷該列表,只要我們知道它們用於哪個模型

 	const QModelIndexList indexes = selectionModel->selectedIndexes();
    for (const QModelIndex &index : indexes) {
        QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());
        model->setData(index, text);
    }

上面的程式碼使用基於範圍的for迴圈來遍歷和修改與選擇模型返回的索引對應的項。

選擇模型發出訊號來指示選擇中的更改。它們通知其他元件關於對整體選擇和專案模型中當前焦點項的更改。
可以將 selectionChanged() 訊號連線到一個槽,並在選擇發生變化時檢查模型中被選中或被取消選中的項。
使用兩個QItemSelection物件呼叫該槽:一個包含對應於新選擇項的索引列表;另一個包含對應於新取消選擇的專案的索引。

更新選定內容:
選擇命令由QItemSelectionModel::SelectionFlag定義的選擇標誌組合提供。每個選擇標誌告訴選擇模型在呼叫select()函式時如何更新所選專案的內部記錄。
最常用的標誌是Select標誌,它指示選擇模型記錄被選中的指定專案。
Toggle標誌使選擇模型反轉指定項的狀態,選擇給定的任何取消選擇的項,並取消選擇任何當前選定的項。取消選擇標誌取消選擇所有指定的專案。

選擇模型中的單個項通過建立一個選擇項來更新,並將它們應用到選擇模型中。在下面的程式碼中,我們將第二個專案選擇應用到上面所示的表模型中,使用Toggle命令來反轉給定專案的選擇狀態。

 	QItemSelection toggleSelection;
    topLeft = model->index(2, 1, QModelIndex());
    bottomRight = model->index(7, 3, QModelIndex());
    toggleSelection.select(topLeft, bottomRight);
    selectionModel->select(toggleSelection, QItemSelectionModel::Toggle);

在這裡插入圖片描述

預設情況下,選擇命令只對模型索引指定的單個項進行操作。用於描述選擇命令的標誌可以與其他標誌結合使用,以更改整個行和列。
例如,如果只使用一個索引呼叫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);

選擇模型中的所有項:

要選擇模型中的所有項,有必要為模型的每個級別建立一個選擇,該級別覆蓋了該級別中的所有項。通過檢索與給定父索引對應的左上和右下項的索引來實現:

	QModelIndex parent = QModelIndex(); //定位模型中的資料
    QModelIndex t = model.index(0,0,parent);
    //rowCount父目錄下的行數。columnCount列。
    QModelIndex b = model.index(model.rowCount(parent)-1,model.columnCount(parent)-1,parent);
    QItemSelection se(t,b);
    selectionModel->select(se,QItemSelectionModel::Select);

對於層次模型,hasChildren()函式用於確定任何給定項是否為另一級別項的父級。

相關文章