(转)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);
结果如下:

读取选择状态
存储在选择模型中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 ¤t,
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);
结果如下:

缺省情况下,选择指令只针对单个项(由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);
结果如下

选择模型中所有项
为了选择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()函数来决定给定项是否是其它项的父项。
(转)Qt Model/View 学习笔记 (六)——在views中选择数据项的更多相关文章
- (转)Qt Model/View 学习笔记 (七)——Delegate类
Qt Model/View 学习笔记 (七) Delegate 类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...
- (转)Qt Model/View 学习笔记 (五)——View 类
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...
- (转)Qt Model/View 学习笔记 (二)——Qt Model/View模式举例
Qt Model/View模式举例 Qt提供了两个标准的models:QStandardItemModel和QDirModel.QStandardItemModel是一个多用途的model,可用于表示 ...
- (转)Qt Model/View 学习笔记 (一)——Qt Model/View模式简介
Qt Model/View模式简介 Qt 4推出了一组新的item view类,它们使用model/view结构来管理数据与表示层的关系.这种结构带来的 功能上的分离给了开发人员更大的弹性来定制数据项 ...
- (转)Qt Model/View 学习笔记 (四)——创建新的Models
创建新的Models 介绍 model/view组件之间功能的分离,允许创建model利用现成的views.这也可以使用标准的功能 图形用户接口组件像QListView,QTableView和QTre ...
- (转)Qt Model/View 学习笔记 (三)——Model类
Model类 基本概念 在model/view构架中,model为view和delegates使用数据提供了标准接口.在Qt中,标准接口QAbstractItemModel类中被定义.不管数据在底层以 ...
- Qt Model/View学习(二)
Model和View的搭配使用 DEMO pro文件 #------------------------------------------------- # # Project created by ...
- iOS 学习笔记六 【APP中的文字和APP名字的国际化多语言处理】
今天为新手解决下APP中的文字和APP名字的国际化多语言处理, 不多说了,直接上步骤: 1.打开你的项目,单机project名字,选中project,直接看图吧: 2.创建Localizable.st ...
- EJB学习笔记六(EJB中的拦截器)
1.前言 听到拦截器,预计都不陌生,尤其是在Servlet规范中,充分应用了拦截器的概念.EJB3也提供了拦截器的支持,本质上是轻量级的AOP实现.拦截器能够将多个业务方法中的通用逻辑从业务方法中抽 ...
随机推荐
- python(1) - 变量小测试
下面看一道题目: a = 3 b = a a = 5 print(a,b) 程序最后输出的a,b值分别是多少呢? 先想一想,然后我们执行一下看看正确答案: 正确答案 a 的值是5, b的值是3,为什么 ...
- 常用html演示模板
--学习测试新的css,js,经常用到test.html,在这里放一个: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transition ...
- Hive中自定义函数
Hive的自定义的函数的步骤: 1°.自定义UDF extends org.apache.hadoop.hive.ql.exec.UDF 2°.需要实现evaluate函数,evaluate函数支持重 ...
- Spring(3.2.3) - Beans(3): Bean 实例的创建方式
创建一个 Bean 实例对象的方法通常有如下方式: 调用构造器创建 Bean 实例 调用静态工厂方法创建 Bean 实例 调用实例工厂方法创建 Bean 实例 使用构造器创建 Bean 实例 XML ...
- JIRA的常用选项
常用的一些选项有: 问题类型 Bug 测试过程维护过程发现影响系统运行的缺陷 New Feature 对系统提出的新功能 Task 需要完成的任务 Improvement 对现有系统功能的改 ...
- ADO.NET笔记(一)XML导入导出和数据库
数据导出成XML文件 #region 数据导出成XML文件 string sql = "select Id, CallerNumber, TelNum, StartDateTime, End ...
- 打造属于自己的安卓Metro界面
前言: 各位小伙伴,又到了每周更新文章了时候了,本来是周日能发出来呢,这不是赶上清明节吗,女王大人发话了,清明节前两天半陪她玩,只留给我周一下午半天时间写博客,哪里有女王哪里就有压迫呀有木有!好了闲话 ...
- asp.net连接oracle的问题及方法总结
.net连oracle数据库的两个方法介绍1. 安装oracle客户端,连接oracle 需要在客户端%oracle_client_home%network/admin/配置tnsnames.ora, ...
- ubuntu 更新软件源
ubuntu 更新软件源 修改文件sources.list 位于/etc/apt/sources.list,并备份原文件为sources.list.bak deb http://mirrors.163 ...
- 相似度到大数据查找之Mysql 文章匹配的一些思路与提高查询速度
文章相关度匹配的一些思路---"压缩"预料库,即提取用特征词或词频,量化后以“列向量”形式保存到数据库:按前N组词拼为向量组供查询使用,即组合为1到N字的组合,量化后以“行向量”形 ...