Qt Model/View 学习笔记 (七)

Delegate  类

概念

与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件。一般来讲, view负责把数据展示

给用户,也处理用户的输入。为了获得更多的灵性性,交互通过delegagte执行。它既提供输入功能又负责渲染view中的每个数据项。 控制delegates的标准接口在QAbstractItemDelegate类中定义。Delegates通过实现paint()和sizeHint()以达到渲染内容的目的。然而,简单的基于widget的delegates,可以从QItemDelegate子类化,而不是QAbstractItemDelegate,这样可以使用它提供的上述函数的缺省实现。delegate可以使用widget来处理编辑过程,也可以直接对事件进行处理。

使用现成的delegate

Qt提供的标准views都使用QItemDelegate的实例来提供编辑功能。它以普通的风格来为每个标准view渲染数据项。这些标准的views包括:QListView,QTableView,QTreeView。所有标准的角色都通过标准views包含的缺省delegate进行处理。一个view使用的delegate可以用itemDelegate()函数取得,而setItemDelegate() 函数可以安装一个定制delegate。

一个简单的delegate

这个delegate使用QSpinBox来提供编辑功能。它主要想用于显示整数的models上。尽管我们已经建立了一个基于整数的table model,但我们也可以使用QStandardItemModel,因为delegate可以控制数据的录入。我们又建了一个table view来显示model的内容,用我们定制的delegate来编辑。

我们从QItemDelegate子类化,这样可以利用它缺省实现的显示功能。当然我们必需提供函数来管理用于编辑的widget:

class SpinBoxDelegate : public QItemDelegate

{

Q_OBJECT

public:

SpinBoxDelegate(QObject *parent = 0);

QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,

const QModelIndex &index) const;

void setEditorData(QWidget *editor, const QModelIndex &index) const;

void setModelData(QWidget *editor, QAbstractItemModel *model,

const QModelIndex &index) const;

void updateEditorGeometry(QWidget *editor,

const QStyleOptionViewItem &option, const QModelIndex &index) const;

};

需要注意的是,当一个delegate创建时,不需要安装一个widget,只有在真正需要时才创建这个用于编辑的widget。

提供编辑器

在这个例子中,当table view需要提供一个编辑器时,它要求delegate提供一个可用于编辑的widget,它应该适用于当前正被修改的数据项。这正是createEditor()函数应该实现的:

QWidget *SpinBoxDelegate::createEditor(QWidget *parent,

const QStyleOptionViewItem &/* option */,

const QModelIndex &/* index */) const

{

QSpinBox *editor = new QSpinBox(parent);

editor->setMinimum(0);

editor->setMaximum(100);

return editor;

}

我们不需要跟踪这个widget的指针,因为view会在不需要时销毁这个widget。我们也给编辑安装了delegate缺省的事件过滤器,这提供了用户期望的标准编辑快捷键。view通过我们定义相应的函数来保证编辑器的数据与几何布局被正确的设置。我们也可以根据不同的model index来创建不同的编辑器,比如,我们有一列整数,一列字符串,我们可以根据哪种列被编辑来创建一个QSpinBox或是QLineEdit。delegate必需提供一个函数把model中的数据拷贝到编辑器中。

void SpinBoxDelegate::setEditorData(QWidget *editor,

const QModelIndex &index) const

{

int value = index.model()->data(index, Qt::DisplayRole).toInt();

QSpinBox *spinBox = static_cast<QSpinBox*>(editor);

spinBox->setValue(value);

}

向model提交数据

这需要我们实现另外一个函数setModelData():

void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,

const QModelIndex &index) const

{

QSpinBox *spinBox = static_cast<QSpinBox*>(editor);

spinBox->interpretText();

int value = spinBox->value();

model->setData(index, value);

}

标准的QItemDelegate类当它完成编辑时会发射closeEditor()信号来通知view。view保证编辑器widget关闭与销毁。本例中我们只提供简单的编辑功能,因此不需要发送个信号。

更新编辑器几何布局

delegate负责管理编辑器的几何布局。这些几何布局信息在编辑创建时或view的尺寸位置发生改变时,

都应当被提供。幸运的是,view通过一个view option可以提供这些必要的信息。

void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,

const QStyleOptionViewItem &option, const QModelIndex &/* index */) const

{

editor->setGeometry(option.rect);

}

编辑提示

编辑完成后,delegate会给别的组件提供有关于编辑处理结果的提示,也提供用于后续编辑操作的一些提示。

这可以通过发射带有某种hint的closeEditor()信号完成。这些信号会被安装在spin box上的缺省的QItemDelegate事件过滤器捕获。对这个缺省的事件过滤来讲,当用户按下回车键,delegate会对model中的数据进行提交,并关闭spin box。

我们可以安装自己的事件过滤器以迎合我们的需要,例如,我们可以发射带有EditNextItem hint的

closeEditor()信号来实现自动开始编辑view中的下一项。

(转)Qt Model/View 学习笔记 (七)——Delegate类的更多相关文章

  1. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  2. (转)Qt Model/View 学习笔记 (一)——Qt Model/View模式简介

    Qt Model/View模式简介 Qt 4推出了一组新的item view类,它们使用model/view结构来管理数据与表示层的关系.这种结构带来的 功能上的分离给了开发人员更大的弹性来定制数据项 ...

  3. (转)Qt Model/View 学习笔记 (二)——Qt Model/View模式举例

    Qt Model/View模式举例 Qt提供了两个标准的models:QStandardItemModel和QDirModel.QStandardItemModel是一个多用途的model,可用于表示 ...

  4. (转)Qt Model/View 学习笔记 (四)——创建新的Models

    创建新的Models 介绍 model/view组件之间功能的分离,允许创建model利用现成的views.这也可以使用标准的功能 图形用户接口组件像QListView,QTableView和QTre ...

  5. (转)Qt Model/View 学习笔记 (三)——Model类

    Model类 基本概念 在model/view构架中,model为view和delegates使用数据提供了标准接口.在Qt中,标准接口QAbstractItemModel类中被定义.不管数据在底层以 ...

  6. (转)Qt Model/View 学习笔记 (六)——在views中选择数据项

    在views中选择数据项 概念 用于新的view类中的选择模型比Qt3中的模型有了很大的改进.它为基于model/view架构的选择提供了更为全面的描述.尽管对提供了的views来说,负责操纵选择的标 ...

  7. Qt Model/View学习(二)

    Model和View的搭配使用 DEMO pro文件 #------------------------------------------------- # # Project created by ...

  8. qt model/view/delegate

    Qt Model/View理解(一)---构造model https://blog.csdn.net/weixin_42303052/article/details/89233887 Qt Model ...

  9. 第15.27节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QTreeWidget详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 树部件(Tree Widget)是Qt Designer中 Item Widgets(It ...

随机推荐

  1. 开发一个struts2的实例

    前面一篇博客(实现struts2框架)带大家对基于mvc业务流程熟悉了一下,现在我们就用对mvc实现最好的框架struts2来开发一个应用实例.虽然现在MyEclipse8.5以上版本已经开始支持St ...

  2. linux 文件夹权限及umask

    先创建一个目录,看看权限: $ ll 总用量 drwxrwxr-x huangxm huangxm 2月 : ./ drwxr-xr-x huangxm huangxm 2月 : ../ drwxrw ...

  3. linux用户及组管理

    useradd      添加用户 passwd       修改用户密码 userdel       删除用户,默认不删除用户主目录和email,如果想删除可加 –r 参数 groupadd   添 ...

  4. Linux系统root用户忘记密码解决方法

    一:在linux系统启动时(如下图),按e键 二:进入到设置页面,定位到如下行: 三:按e键,进入输入界面 四:在编辑行最后面,空格,输入single,回车后回到第二步界面,只是后面多了single ...

  5. Bash循环分类介绍

    方法一: #!/bin/bash ` do #code here echo $i done 方法二:C语言风格 #!/bin/bash ; i<=; i++)) do printf " ...

  6. [转]T4模版引擎之生成数据库实体类

    本文转自:http://www.cnblogs.com/lzrabbit/archive/2012/07/18/2597953.html 在通过T4模版引擎之基础入门 对T4有了初步印象后,我们开始实 ...

  7. 跟我一起学习VIM - The Life Changing Editor

    前两天同事让我在小组内部分享一下VIM,于是我花了一点时间写了个简短的教程.虽然准备有限,但分享过程中大家大多带着一种惊叹的表情,原来编辑器可以这样强大,这算是对我多年来使用VIM的最大鼓舞吧.所以分 ...

  8. BZOJ 1012

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 7912  Solved: 3441[Submi ...

  9. MyBatis(3.2.3) - hello world

    1. 创建数据表(MySQL): DROP TABLE IF EXISTS `department`; CREATE TABLE `department` ( `did` ) unsigned NOT ...

  10. Contoso 大学 - 6 – 更新关联数据

    原文 Contoso 大学 - 6 – 更新关联数据 By Tom Dykstra, Tom Dykstra is a Senior Programming Writer on Microsoft's ...