簡述
項目視圖類使用選擇模型
提供一種對選擇行爲的通用描述。
項目的選擇狀態信息被存儲在QItemSelectionModel類的實例中。
QItemSelectionModel維護着選擇實體
(QItemSelection),選擇實體
由選擇範圍構成,一個選擇範圍只需要起點(start index)和終點(end index)便可唯一確定。非連續的選擇選擇範圍則需要多個選擇範圍來描述。
提示: 當進行選擇操作時,可以將項目視圖中使用的選擇模型(QItemSelectionModel)看做是項目模型中項目的選擇狀態監控器
。
當前項目和被選擇的項目
在一個視圖中,總有兩種獨立狀態:當前項目、被選擇的項目。一定要將兩者清楚地區分開。
下面是二者的不同:
當前項目 | 被選擇的項目 |
---|---|
只能有一個當前項目 | 可以有多個被選擇的項目 |
當前項目可以通過鍵盤按鍵或者鼠標點擊來改變 | 當用戶與項目進行交互時,根據幾種預定義模式(例如,單選,多選等)來設置或取消設置項目的選定狀態。 |
如果按下編輯鍵F2或雙擊該項目,則當前項目將被編輯(前提是啓用了編輯)。 | 當前項目可與錨點一起使用,以指定應選擇或取消選擇的範圍(或兩者的組合)。 |
當前項目由焦點矩形指示。 | 所選項目用選擇矩形表示。 |
使用選擇模型
標準視圖類爲大多數應用提供了默認的選擇模型
。可以通過selectionModel()來獲取視圖的模型,可以通過setSelectionModel()來設置新的選擇模型
。
通過將一對模型索引傳遞給QItemSelection來創建一個選擇。這對模型索引中,一個表示選擇起點,一個表示選擇終點。爲了將選擇應用到項目上,我們還需要將創建的選擇提交給選擇模型
。根據提交時附加的選擇模式,最終會出現特定的選擇效果。使用方法如下:
//設置選擇起始點
topLeft = model->index(1, 1, QModelIndex());
bottomRight = model->index(2, 2, QModelIndex());
//創建選擇
QItemSelection selection(topLeft, bottomRight);
//將選擇提交給選擇模型
selectionModel->select(selection, QItemSelectionModel::Select);
效果如下:
常見操作
讀取選擇狀態
可以通過selectedIndexes()來讀取選擇模型
中的模型索引,如下所示
QModelIndexList indexes = selectionModel->selectedIndexes();
QModelIndex index;
foreach(index, indexes) {
QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());
model->setData(index, text);
}
效果
通過遍歷所有選中的項目,對這些項目進行賦值。
當選擇狀態改變的時候,選擇模型會發出信號來指示這種變化,可以編寫相應的槽函數來處理這個信號。下面的代碼展示了這樣一個槽函數。
void Widget::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, "");
}
信號槽綁定:
connect(selectionModel, &QItemSelectionModel::selectionChanged,this,
&Widget::updateSelection);
效果
多模式選擇
我們通過如下命令來對特定的區域執行特定的操作:
selectionModel->select(selection, QItemSelectionModel::Select);
其中的QItemSelectionModel::Select來自QItemSelectionModel::SelectionFlag,這個枚舉類型定義了像清除、選擇、取消選擇、反選、整行選擇、整列選擇等等,這些枚舉值也可以進行組合使用,下面舉兩個例子來說明:
反選操作
QItemSelection toggleSelection;
topLeft = model->index(2, 1, QModelIndex());
bottomRight = model->index(7, 3, QModelIndex());
toggleSelection.select(topLeft, bottomRight);
selectionModel->select(toggleSelection, QItemSelectionModel::Toggle);
整行整列選擇
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 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);
對於層級結構,hasChildren()函數被用來判斷給定的項目是否是另一些項目的父代。
引用
[1] Qt助手