Qt 使用QItemSelectionModel
类获取视图中项目的选择情况。这个模型保持有项目的索引,并且独立于任何视图。这意味着,我们可以让不同的视图共享同一个选择模型,从来达到一种同步操作的目的。选择由选择区域组成。模型只将选区的开始和结束的索引位置记录下来,以保证对于很大的选区也有很好的性能。非连续选区则由多个连续选择组成。
选择会直接应用于选择模型所维护的那些被选中的索引上面。最新的选择就是当前选择。这意味着,即便界面上没有显示有任何项目被选择,如果通过某些命令对选区进行操作,同样会有作用。
在视图中,始终存在一个当前项和被选择项(即便从界面上看不到有任何选择)。与通常所想的不同,当前项和选择项是相互独立的两个状态。一个项目可以即是当前项又是选择项。下表是当前项和选择项的区别:
当前项 | 选择项 |
---|---|
只能有一个当前项。 | 可以有多个选择项。 |
使用键盘或者鼠标点击可以改变当前项。 | 选择项使用两种状态:选择和未选择,这取决于项目之前的状态和其它一些设置,例如,单选或多选。只有在用户进行交互的时候,这种状态才会发生改变。 |
当前项可以使用 F2 或者鼠标双击进行编辑(前提是程序允许)。 | 当前项可以结合另外一个锚点指定被选择或者去除选择的一块选区(或二者的结合)。 |
当前项通常会有一个焦点框进行标识。 | 选择项使用选区颜色进行标识。 |
在处理选择的时候,我们可以将QItemSelectionModel
当成数据模型中所有数据项的选择状态的一个记录。一旦选择模型创建好,这些数据项就可以在不知道哪些项被选择的情况下进行选择、取消选择或者改变选择状态的操作。所有被选择项的索引都在可随时更改,其它组件也可以通过信号槽机制修改这些选择的信息。
标准视图类(QListView
、QTreeView
以及QTableView
)已经提供了默认的选择模型,足以满足大多数应用程序的需求。某一个视图的选择模型可以通过selectionModel()
函数获取,然后使用setSelectionModel()
提供给其它视图共享,因此,一般没有必要新建选择模型。
如果需要创建一个选区,我们需要指定一个模型以及一对索引,使用这些数据创建一个QItemSelection
对象。这两个索引应该指向给定的模型中的数据,并且作为一个块状选区的左上角和右下角的索引。为了将选区应用到模型上,需要将选区提交到选择模型。这种操作有多种实现,对于现有选择模型有着不同的影响。
下面我们来看一些代码片段。首选构建一个总数 32 个数据项的表格模型,然后将其设置为一个表格视图的数据:
1
2
3
|
QTableWidget tableWidget(8, 4);
QItemSelectionModel *selectionModel = tableWidget.selectionModel();
|
在代码的最后,我们获得QTableView
的选择模型,以备以后使用。现在,我们没有修改模型中的数据,而是选择表格左上角的一些单元格。下面我们来看看代码如何实现:
1
2
|
QModelIndex topLeft = tableWidget.model()->index(0, 0, QModelIndex());
QModelIndex bottomRight = tableWidget.model()->index(5, 2, QModelIndex());
|
接下来,我们将获得的两个索引定义为选区。为达这一目的,我们首先构造一个QItemSelection
对象,然后将其赋值给我们获取的选择模型:
1
2
|
QItemSelection selection(topLeft, bottomRight);
selectionModel->select(selection, QItemSelectionModel::Select);
|
正如前面我们说的,首先利用左上角和右下角的坐标构建一个QItemSelection
对象,然后将这个对象设置为选择模型的选择区。select()
函数的第一个参数就是需要选择的选区,第二个参数是选区的标志位。Qt 提供了很多不同的操作,可以参考下QItemSelectionModel::SelectionFlags
的文档。在本例中,我们使用了QItemSelectionModel::Select
,这意味着选区中所包含的所有单元格都会被选择。
下面就是我们的运行结果:
现在我们知道如何设置选区。下面来看看如何获取选区。获取选区需