简述
项目视图类使用选择模型
提供一种对选择行为的通用描述。
项目的选择状态信息被存储在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助手