Qt Model/View之代理

news2024/9/20 18:46:15

概念

与模型-视图-控制器模式不同,模型/视图设计没有包含一个完全独立的组件来管理与用户的交互。通常,视图负责向用户展示模型数据,并负责处理用户输入。为了在获取输入的方式上具有一定的灵活性,交互由委托执行。这些组件提供输入功能,还负责在某些视图中渲染单个项目。控制委托的标准接口定义在QAbstractItemDelegate类中。

委托希望能够通过实现paint()和sizeHint()函数来渲染它们自己的内容。然而,简单的基于部件的委托可以继承QStyledItemDelegate而不是QAbstractItemDelegate,并利用这些函数的默认实现。

委托编辑器可以通过使用小部件来管理编辑过程,也可以通过直接处理事件来实现。第一种方法将在本节后面介绍,它也会在Spin Box委托的例子中展示。

Pixelator的例子展示了如何创建一个自定义委托来为tableview执行特殊的渲染。

使用现有委托

Qt提供的标准视图使用QStyledItemDelegate实例来提供编辑功能。delegate接口的默认实现会以标准视图(QListView、QTableView和QTreeView)的通常风格渲染元素。

所有标准角色都由标准视图使用的默认委托处理。解释它们的方式在QStyledItemDelegate文档中有描述。

视图使用的委托由itemDelegate()函数返回。setItemDelegate()函数允许你为标准视图安装一个自定义委托,在为自定义视图设置委托时,必须使用这个函数。

一个简单的委托

这里实现的委托使用QSpinBox来提供编辑功能,主要用于显示整数的模型。虽然我们为此设置了一个自定义的基于整数的表模型,但我们可以轻松地使用QStandardItemModel,因为自定义委托控制数据输入。我们构建一个表视图来显示模型的内容,这将使用自定义委托进行编辑。

我们从QStyledItemDelegate继承委托的子类,因为我们不想编写自定义显示函数。但是,我们仍然必须提供管理编辑器小部件的函数:

class SpinBoxDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    SpinBoxDelegate(QObject *parent = nullptr);

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override;

    void setEditorData(QWidget *editor, const QModelIndex &index) const override;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override;

    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
                              const QModelIndex &index) const override;
};

注意,构造委托时没有设置编辑器部件。我们只在需要时构建编辑器部件。

提供编辑器

在这个例子中,当表视图需要提供一个编辑器时,它要求委托提供一个适合于正在修改的项的编辑器部件。createEditor()函数提供了委托设置适当部件所需的一切:

QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
                                       const QStyleOptionViewItem &/* option */,
                                       const QModelIndex &/* index */) const
{
    QSpinBox *editor = new QSpinBox(parent);
    editor->setFrame(false);
    editor->setMinimum(0);
    editor->setMaximum(100);

    return editor;
}

请注意,我们不需要保留指向编辑器部件的指针,因为当不再需要它时,视图会负责销毁它。

我们在编辑器上安装了委托的默认事件过滤器,以确保它提供了用户期望的标准编辑快捷方式。可以向编辑器添加额外的快捷方式,以允许更复杂的行为;这些将在编辑提示一节中讨论。

视图通过调用我们后面为这些目的定义的函数来确保编辑器的数据和几何信息被正确设置。我们可以根据视图提供的模型索引创建不同的编辑器。例如,如果我们有一列整数和一列字符串,我们可以返回QSpinBox或QLineEdit,这取决于正在编辑哪一列。

委托必须提供将模型数据复制到编辑器中的函数。在这个例子中,我们读取了存储在display角色中的数据,并相应地设置了spin box中的值。(设置编辑器的值

void SpinBoxDelegate::setEditorData(QWidget *editor,
                                    const QModelIndex &index) const
{
    int value = index.model()->data(index, Qt::EditRole).toInt();

    QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
    spinBox->setValue(value);
}

在这个例子中,我们知道编辑器小部件是一个spin box,但我们可以为模型中的不同类型的数据提供不同的编辑器,在这种情况下,我们需要在访问其成员函数之前将小部件转换为适当的类型。

向模型提交数据

当用户完成微调框中的值编辑后,视图会调用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, Qt::EditRole);
}

由于视图为委托管理编辑器部件,我们只需要使用提供的编辑器内容更新模型。在本例中,我们确保微调框是最新的,并使用指定的索引用它包含的值更新模型。

标准的QStyledItemDelegate类通过发出closeEditor()信号来通知视图何时完成编辑。视图确保编辑器部件被关闭和销毁。在这个例子中,我们只提供了简单的编辑功能,所以我们永远不需要发射这个信号。

所有对数据的操作都通过QAbstractItemModel提供的接口来执行。这使得委托基本上独立于它所操作的数据类型,但是为了使用某些类型的编辑器部件,必须做一些假设。在这个例子中,我们假设模型总是包含整数值,但我们仍然可以将此委托用于不同类型的模型,因为QVariant为意外数据提供了合理的默认值。

更新编辑器的几何形状

委托的职责是管理编辑器的几何图形。几何形状必须在编辑器创建时设置,并且当项目的大小或在视图中的位置发生变化时设置。幸运的是,该视图在视图选项对象中提供了所有必要的几何信息。

void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
                                           const QStyleOptionViewItem &option,
                                           const QModelIndex &/* index */) const
{
    editor->setGeometry(option.rect);
}

在这个例子中,我们只使用项目矩形中的view选项提供的几何信息。呈现具有多个元素的项的委托不会直接使用项矩形。它将使编辑器相对于项目中的其他元素进行定位。

编辑提示

在编辑之后,委托应该向其他组件提供有关编辑过程结果的提示,并提供有助于任何后续编辑操作的提示。这是通过发送带有适当提示的closeEditor()信号来实现的。这是由默认的QStyledItemDelegate事件过滤器处理的,我们在构建spin box时安装了它。

可以调整spin box的行为,使其对用户更友好。在QStyledItemDelegate提供的默认事件过滤器中,如果用户点击Return来确认他们在微调框中的选择,则委托将值提交给模型并关闭微调框。我们可以通过在微调框上安装自己的事件过滤器来改变这种行为,并根据需要提供编辑提示;例如,我们可以发送带有EditNextItem提示的closeEditor(),以自动开始编辑视图中的下一项。

另一种不需要使用事件过滤器的方法是提供我们自己的编辑器部件,为了方便,可能会子类化QSpinBox。这种替代方法将使我们能够更多地控制编辑器部件的行为,但代价是编写额外的代码。如果需要自定义标准Qt编辑器部件的行为,在委托中安装事件过滤器通常更容易。

委托不必发出这些提示,但是那些不发出提示的委托与应用程序的集成程度较低,而且与那些发出提示以支持常见编辑操作的委托相比,它们的可用性较差。

Model/View Programming | Qt Widgets 5.15.17

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2135985.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5 个最佳开源无代码项目管理工具

想象一下&#xff0c;你是一名项目经理&#xff0c;每天早上刚坐到办公桌前&#xff0c;咖啡还在手里&#xff0c;你的手机和电脑屏幕上已经被各种未完成的任务、项目更新和团队消息填满。 你快速浏览着的电子邮件&#xff0c;分配任务的通知不断弹出&#xff0c;而每一个通知…

Shopee虾皮:广告类型选择与效果优化要点

Shopee虾皮作为东南亚增势迅猛的电商平台&#xff0c;是很多跨境卖家出海东南亚的首要选择。这势必带来强烈的竞争&#xff0c;因此&#xff0c;如果卖家想要突出重围&#xff0c;广告投放和优化则格外重要。 一、虾皮的广告类型 1.关键词广告 当买家搜索的关键字与卖家投放的…

进程优先级和环境变量

1.优先级 1.优先级的概念 cpu资源分配的先后顺序&#xff0c;就是指进程的优先级&#xff0c;linux中进程的优先级数字越小&#xff0c;优先级越高&#xff1b; 2.为什么要有优先级 进程访问的资源(cpu)始终是有限的&#xff0c;而系统中进程又是比较多的&#xff0c;所以进…

【Jetson】Jetson Orin NX刷机教程

Jetson Orin NX刷机教程 一、硬件准备二、安装SDK Manager三、在线或离线刷机 一、硬件准备 需要将Jetson Orin NX的GND和FC_REC引脚短接&#xff0c;设备进入刷机模式。然后用Type-C线将其余主机连接&#xff0c;主机的选择可以为ubuntu虚拟机或者ubuntu系统。注意如果选择虚…

Mybatis接受查询结果的情况

Mybatis接受查询结果的情况 1.查询结果为单条数据时 1&#xff09;通过实体类对象接受 这种方式最直观&#xff0c;当查询结果只有一条记录时使用。在 mapper 接口中定义一个方法&#xff0c;并指定返回类型为对应的实体类类型。mapper.xml 文件中的 <select> 标签使用…

vue3项目打包后多级嵌套路由子路由刷新后空白问题

问题描述 Vue3项目打包发布后&#xff0c;进入个人中心界面,刷新后页面出现空白。前提是已经配置了重定向到index.html。在访问/personal/profile这种路由的时候刷新后页面会出现空白。在App.vue中有一个routerview ,personal界面中有一个routerview .界面如图所示 router.js…

【Python基础】Python错误和异常处理(详细实例)

本文收录于 《Python编程入门》专栏&#xff0c;从零基础开始&#xff0c;分享一些Python编程基础知识&#xff0c;欢迎关注&#xff0c;谢谢&#xff01; 文章目录 一、前言二、Python中的错误类型三、Python异常处理机制3.1 try-except语句3.2 try-except-else语句3.3 try-fi…

GD - GD32350R_EVAL - PWM实验和验证2 - EmbeddedBuilder - 无源蜂鸣器

文章目录 GD - GD32350R_EVAL - PWM实验和验证2 - EmbeddedBuilder - 无源蜂鸣器概述笔记先前失败的实验电路图本次成功的图 - 无源蜂鸣器电路模块接入实验模块实验软件工程主循环实现PWM频率改变蜂鸣器声音大小实验结果和官方给的蜂鸣器频率响应曲线基本一样看看实际波形END G…

智慧交通基于yolov8的行人车辆检测计数系统python源码+onnx模型+精美GUI界面

【算法介绍】 智慧交通中&#xff0c;基于YOLOv8的行人车辆检测计数系统是一项高效、准确的技术解决方案。该系统利用YOLOv8这一先进的目标检测算法&#xff0c;结合深度学习技术&#xff0c;能够实时检测并准确计数道路上的行人和车辆。YOLOv8在保证检测速度的同时&#xff0…

视图(mysql)

一、什么是视图 视图是⼀个虚拟的表&#xff0c;它是基于⼀个或多个基本表或其他视图的查询结果集。视图本⾝不存储数 据&#xff0c;⽽是通过执⾏查询来动态⽣成数据。⽤⼾可以像操作普通表⼀样使⽤视图进⾏查询、更新和管 理。视图本⾝并不占⽤物理存储空间&#xff0c;它仅…

linux命令用于删除文本文件中的重复行的命令uniq详解

目录 一、概述 二、基本用法 1、uniq 命令的基本语法 2、常用选项 3、获取帮助 三、主要功能 1. 识别并删除相邻重复行 2. 保留重复行的第一个实例 3. 统计重复次数 4. 忽略指定列的比较 四、示例 1. 删除相邻重复行 2. 显示每一行及其重复次数 3. 只显示重复行 4. …

【Hot100】LeetCode—136. 只出现一次的数字

目录 1- 思路题目识别技巧 2- 实现⭐136. 只出现一次的数字——题解思路 原题链接&#xff1a;136. 只出现一次的数字 1- 思路 题目识别 识别1 &#xff1a;给定一个数组&#xff0c;里面元素均出现两次&#xff0c;只有一个数只出现一次。 技巧 一个数和 0 的异或是这个数…

前端网页代码编辑器 Monaco Editor

前端网页代码编辑器 Monaco Editor Monaco Editor Monaco Editor 是由 Microsoft 开发的一款基于 Web 技术的开源代码编辑器&#xff0c;它是 Visual Studio Code 编辑器的核心。Monaco Editor 可以嵌入到网页中&#xff0c;提供类似于 Visual Studio Code 的编辑体验。 官方…

华为SMU02B1管理模块WEB登录与账户密码信息

1、将电脑的IP地址与SMU02B1的IP地址配置在同一个网段中。例如&#xff0c;如果监控的IP地址为192.168.0.11&#xff0c;子网掩码为255.255.255.0&#xff0c;默认网关为192.168.0.1&#xff0c;则电脑的IP地址设置成192.168.0.12&#xff0c;子网掩码设置成255.255.255.0&…

基于微信小程序的垃圾分类(lw+演示+源码+运行)

摘 要 随着生态文明体制改革的不断推进,可持续发展的环保理念逐渐成为社会共识,而在推行环保措施的过程中却困难重重.针对生活废弃物肆意无序投放的问题,尽管目前各大城市相继推出垃圾分类强制性执行的政策法规,但因市民欠缺对垃圾种类的正确认识而导致垃圾分类的施行难度和成…

【Docker系列】环境准备-VirtualBox虚拟机安装

前言 最近一段时间研究了一下Docker容器方面的技术&#xff0c;发现容器技术还是蛮好玩的。但是自己手头上没啥Linux操作系统机器&#xff0c;于是就想到利用一些虚拟机软件工具&#xff0c;在自己的Windows操作系统上安装几个Linux操作系统环境。我这里给大家介绍的是一款常用…

【代码随想录训练营第42期 Day58打卡 - 图论Part8 - 拓扑排序

目录 一、拓扑排序介绍 定义 特点 实现方法&#xff08;2种&#xff09; 应用 二、题目与题解 题目&#xff1a;卡码网 117. 软件构建 题目链接 题解&#xff1a;拓扑排序 - Kahn算法&#xff08;BFS&#xff09; 三、小结 一、拓扑排序介绍 对于拓扑排序&#xff0c…

【传纸条 / NOIP / Google】

题目 代码&#xff08;还是我的好理解&#xff0c;(●◡●)&#xff09; #include <bits/stdc.h> using namespace std; const int N 55; int w[N][N]; int f[2*N][N][N]; int main() {int m, n;cin >> m >> n;for(int i 1; i < m; i){for(int j 1; j…

ASPCMS靶场漏洞复现

浏览器访问环境 1.进入后台管理 aspcms默认的后台登录地址为/admin_aspcms/index.asp 用户名&#xff1a;admin 密码&#xff1a;123456 2.点击扩展功能里面的幻灯片设置 3.在保存的时候抓包 抓包修改slideTextStatus参数为一句话木马 1%25><%25Eval(Request (chr(65…

【CSS】选择器(基本选择器、复合选择器、属性匹配选择器、结构伪类选择器、伪元素选择器)

选择器 引入方式基础选择器复合选择器属性匹配选择器结构伪类选择器伪元素选择器 引入方式 1&#xff1a;外联 <!-- css引入方式1&#xff1a;外联 外联与内嵌优先级相同&#xff0c;取决于加载顺序 --><link rel"stylesheet" href"./样式.css"…