概念
不同于模型 - 视图 - 控制器模式,模型/视图设计不包括用于管理与用户交互的一个完全独立的组件。一般情况,视图负责将模型数据呈现给用户以及处理用户输入。为了输入更加具有灵活性,则由委托来执行交互。这些组件提供输入功能,且在一些视图中还负责渲染个别项目。控制委托的标准接口在QAbstractItemDelegate类中定义。
委托能够通过实现的paint()和sizeHint()函数来展示它们的内容。然而,简单基础部件的委托可以继承QItemDelegate而不是QAbstractItemDelegate,并使用这些函数的默认实现。
委托编辑器可以通过使用小工具来管理编辑过程或直接处理事件来实现。

使用现有委托
Qt提供的标准视图中使用QItemDelegate提供编辑功能。委托接口的默认实现以一贯风格来呈现项目为每个标准视图:QListView、QTableView、QTreeView。
所有标准角色由所使用的标准视图中的默认委托处理。
视图使用委托是由itemDelegate()函数返回。setItemDelegate()函数允许你为标准视图设定一个自定义委托,为自定义视图设定委托时,有必要使用此功能。

一个简单的委托
这里实现的委托使用QSpinBox来提供编辑功能,主要用于模型处理整数。虽然为了这个目的我们设置了一个自定义的基于整数的表模型,我们可以很容易地使用QStandardItemModel来代替,因为自定义委托控制数据输入。我们构造了一个表视图来显示模型的内容,可以使用自定义的委托来进行编辑。

我们的委托继承于QItemDelegate,因为我们不想编写自定义显示功能。然而,仍然必须提供管理编辑器窗口小部件的功能:
class SpinBoxDelegate : public QStyledItemDelegate
{
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;
};
提供了一个编辑器
在这个例子中,当表视图需要提供一个编辑器时,它将要求委托提供一个编辑器部件适用于修改该项目。createEditor()函数提供一切,委托需要能够建立一个合适的窗口小部件:
QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &,
const QModelIndex &) const
{
QSpinBox *editor = new QSpinBox(parent);
editor->setFrame(false);
editor->setMinimum(0);
editor->setMaximum(100);

return editor; }
注意,我们不需要一个指向编辑器的部件,因为当不再需要时,视图负责销毁它。
在编辑器上安装代理的默认事件过滤器,以确保它提供了用户所期望的标准编辑快捷方式。编辑器中可以添加额外的快捷键,以允许更复杂的行为。
可以根据视图提供的模型索引创建不同的编辑器。例如,如果有一个整数列和字符串列,我们可以返回一个QSpinBox或QLineEdit,这取决于哪一列正在被编辑。
委托必须提供一个函数将模型中的数据复制到编辑器中。在这个例子中,我们读出存储在显示角色中的数据,并在QSpinBox中设置的值相应。
void SpinBoxDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
int value = index.model()->data(index, Qt::EditRole).toInt();
QSpinBox *spinBox = static_cast<<span style=" color:#800080;">QSpinBox*>(editor);
spinBox->setValue(value);
}
在这个例子中,我们知道编辑器部件是一个QSpinBox,但可以为模型中不同类型的数据提供不同的编辑器,在这种情况下,则需要在访问它的成员函数之前设置部件为适当的类型。
void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QSpinBox *spinBox = static_cast<<span style=" color:#800080;">QSpinBox*>(editor);
spinBox->interpretText();
int value = spinBox->value();
model->setData(index, value, Qt::EditRole);
}
由于视图为委托管理编辑器部件,所以只需要以编辑器提供的内容来更新模型。在这种情况下,我们确QSpinBox是最新更新,并使用指定的索引包含的值来更新模型。
标准的QItemDelegate类通过发射closeEditor()信号来完成编辑视图。视图可确保编辑器部件被关闭和销毁。在这个例子中,我们只提供简单的编辑功能,所以我们需要永远不会发出这个信号。
所有的数据操作通过QAbstractItemModel提供的接口执行。这使得委托大多独立于它操纵的数据的类型,但为了使用某些类型的编辑器部件,则必须做出一些假设。在这个例子中,我们假设模型总是包含整数值,但我们仍然在不同类型的模型中使用此委托,因为的QVariant为意想不到的数据提供了合理的默认值。

更新编辑器的几何形状
管理编辑器的几何形状是委托的责任。当编辑器被创建,或者当项目视图的的位置、大小在视图中改变时,几何形状必须被设置。幸运的是,视图提供了视图选项物体内部所有必要的几何信息。
void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &) const
{
editor->setGeometry(option.rect);
}
这种情况下,我们仅在项目区域中使用视图选项提供的位置信息。使用一些元素展现项目的委托不会直接使用该项目矩形。根据这个项目中的其他元素来设定编辑器的位置。
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QStandardItemModel model(4, 2);
QTableView tableView;
tableView.setModel(&model);
SpinBoxDelegate delegate;
tableView.setItemDelegate(&delegate);
tableView.horizontalHeader()->setStretchLastSection(true);
for (int row = 0; row <<span style=" color:#c0c0c0;"> 4; ++row) {
for (int column = 0; column <<span style=" color:#c0c0c0;"> 2; ++column) {
QModelIndex index = model.index(row, column, QModelIndex());
model.setData(index, QVariant((row + 1) * (column + 1)));
}
}
tableView.setWindowTitle(QObject::tr("Spin Box Delegate"));
tableView.show();
return app.exec();
}

Qt之模型/视图(委托)的更多相关文章

  1. 【转】Qt之模型/视图

    [本文转自]http://blog.sina.com.cn/s/blog_a6fb6cc90101hh20.html   作者: 一去丶二三里 关于Qt中MVC的介绍与使用,助手中有一节模型/视图编程 ...

  2. Qt之模型/视图(自定义风格)

    Qt之模型/视图(自定义风格) 关于自定义风格是针对视图与委托而言的,使用事件与QSS都可以进行处理,今天关于美化的细节讲解一下. 先看下图: 先撇开界面的美观性(萝卜青菜,各有所爱),就现有的这些风 ...

  3. PyQt5模型视图委托

    Model-View-Delegate 模型视图委托(MVD)是PyQt中特有的设计模式,类似MVC设计模式,将MVC设计模式中的Controller当做MVD中的Delegate,两者的概念基本相同 ...

  4. Qt 模型/视图/委托

    模型.视图.委托 模型/视图架构基于MVC设计模式发展而来.MVC中,模型(Model)用来表示数据:视图(View)是界面,用来显示数据:控制(Controller)定义界面对用户输入的反应方式. ...

  5. Qt之模型/视图(自定义进度条)

    简述 在之前的章节中分享过关于QHeaderView表头排序.添加复选框等内容,相信大家模型/视图.自定义风格有了一定的了解,下面我们来分享一个更常用的内容-自定义进度条. 实现方式: 从QAbstr ...

  6. Qt之模型/视图(实时更新数据)

    上两节简单介绍了Qt中对于模型/视图的编程,大部分助手里说的很清楚了,现在就开始实战部分吧! 在实际应用中,视图展示的数据往往并非一成不变的,那么如何实时更新成了一个很重要的问题!功能:(1)添加委托 ...

  7. QT MVC 模型/视图

    1. 模型视图实例一, QFileSystemModel  QTreeView ,model/view示例. #include <QApplication> #include <QF ...

  8. Qt之模型/视图(委托)

    # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' from PyQt4.Qt import * from PyQt4. ...

  9. Qt MVC(模型-视图-代理)

    实习刚才是一段时间,公司这边就要求熟悉这个mvc.一般开始都是用tableview,前面的blog我都是使用listview居多,并且相对delegate这个使用的多余model.接下来说下model ...

随机推荐

  1. 如何通过wlst部署应用程序到weblogic12c上

    适用版本 Oracle WebLogic Server - Version 10.3 and laterInformation in this document applies to any plat ...

  2. OpenStack kilo版(5) Neutron部署

    neutron简介: Neutron 通过 plugin 和 agent 提供的网络服务. plugin 位于 Neutron server,包括 core plugin 和 service plug ...

  3. synchronize与lock

    1. synchronize的作用 synchronize是java最原始的同步关键字,通过对方法或者代码块进行加锁实现对临界区域的保护.线程每次进去同步方法或者代码块都需要申请锁,如果锁被占用则会等 ...

  4. Android笔记(二十六) Android中的广播——BroadcastReceiver

    为了方便进行系统级别的消息通知,Android有一套类似广播的消息机制,每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收自己所关心的广播内容,这些广播可能是来自于系统,也可能是来自于 ...

  5. Android笔记 (二) Android的核心---Activity

    什么是Activity Activity是Android应用程序核心组件中最基本的一个,是用户和程序交互的窗口,一个activity通常对应一个单独的视图,一个APP由一个或者多个activity构成 ...

  6. sql的时间格式

    sql中的时间格式转换主要有:date_format函数,str_to_date函数 1. 首先选择一个数据库 use db_name; 2. 显示当前时区的时间: SELECT NOW(); 3. ...

  7. 科大讯飞语音识别Demo创建

    1.下载官方SDK https://www.xfyun.cn/sdk/dispatcher 2.打开AS,选择import project 3.导入mscV5PlusDemo  4.解决ERROR: ...

  8. orm多表的创建和基于对象的查询

    创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关系( ...

  9. Vim使用技巧(5) -- 宏的录制与使用

    想象一个场景,我们怎么快速把下面的所有链接都加上双引号?可能你手速快,可以很快的加完,但是如果链接有上万个呢?你如何在十秒以内加完? 这时候就需要用到“宏”(其实除了宏vim还有其它方法加上双引号,这 ...

  10. 【转】Senior Data Structure · 浅谈线段树(Segment Tree)

    本文章转自洛谷 原作者: _皎月半洒花 一.简介线段树 ps: _此处以询问区间和为例.实际上线段树可以处理很多符合结合律的操作.(比如说加法,a[1]+a[2]+a[3]+a[4]=(a[1]+a[ ...