Qt 模型视图(四):代理类QAbstractItemDelegate

文章目录

  • Qt 模型视图(四):代理类`QAbstractItemDelegate`
    • 1.基本概念
      • 1.1.使用现有代理
      • 1.2.一个简单的代理
    • 2.提供编辑器
    • 3.向模型提交数据
    • 4.更新编辑器的几何图形
    • 5.编辑提示

Qt 模型视图(四):代理类QAbstractItemDelegate

模型/视图结构是一种将数据存储界面展示分离的编程方法。模型存储数据,视图组件显示模型中的数据,在视图组件里修改的数据会被自动保存到模型里。模型的数据来源可以是内存中的字符串列表或二维表格型数据,也可以是数据库中的数据表,一种模型可以用不同的视图组件来显示数据,所以模型/视图结构是一种高效、灵活的编程结构。

1.基本概念

与模型-视图-控制器模式不同,模型/视图设计不包括一个完全独立的组件来管理与用户的交互。通常,视图负责向用户呈现模型数据,并处理用户输入。为了使获得此输入的方式具有一定的灵活性,交互由代表执行。这些组件提供输入功能,还负责在某些视图中呈现单个项目。控制委托的标准接口在QAbstractItemDelegate类中定义。
委托应该能够通过实现paint()和sizeInt()函数来呈现自己的内容。但是简单的基于小部件的委托可以子类化QStyleItemDelegate替代QAbstractItemDelegate,并利用这些函数的默认实现。
代理的编辑器可以通过使用小部件来管理编辑过程或直接处理事件来实现。稍后将介绍第一种方法。

1.1.使用现有代理

Qt提供的标准视图使用QStyleItemDelegate的实例来提供编辑功能。委托接口的此默认实现以每个标准视图的常用样式呈现项目:QListView、QTableView和QTreeView
所有标准角色都由标准视图使用的默认委托处理。QStyledItemDelegate文档中描述了这些内容的解释方式。
视图使用的委托由itemDelegate()函数返回。setItemDelegate()函数允许您为标准视图安装自定义委托,在为自定义视图设置委托时必须使用此函数。

1.2.一个简单的代理

这里实现的委托使用QSpinBox提供编辑功能,主要用于显示整数的模型。尽管我们为此目的设置了一个基于整数的自定义表模型,但我们本可以很容易地使用QStandardItemModel,因为自定义委托控制着数据输入。我们构造了一个表视图来显示模型的内容,这将使用自定义委托进行编辑。
在这里插入图片描述
我们将委托从QStyleItemDelegate子类化,因为我们不想编写自定义显示函数。但是,我们仍然必须提供管理编辑器小部件的功能:

 class SpinBoxDelegate : public QStyledItemDelegate{Q_OBJECTpublic: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;};SpinBoxDelegate::SpinBoxDelegate(QObject *parent): QStyledItemDelegate(parent){}

请注意,在构造委托时不会设置编辑器小部件。我们只在需要时构建编辑器小部件。

2.提供编辑器

在这个例子中,当表视图需要提供编辑器时,它会要求委托提供一个适合被修改项目的编辑器小部件。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,具体取决于正在编辑的列。
委托必须提供将模型数据复制到编辑器中的函数。在这个例子中,我们读取存储在显示角色中的数据,并相应地在旋转框中设置值。

 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);}

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

3.向模型提交数据

当用户在数字设定框中编辑完值后,视图会调用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为意外数据提供了合理的默认值。

4.更新编辑器的几何图形

管理编辑器的几何图形是代理的责任。创建编辑器,更改项目在视图中的大小或位置时,必须设置几何图形。幸运的是,视图在视图选项对象中提供了所有必要的几何信息。

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

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

5.编辑提示

编辑后,代理应向其他组件提供有关编辑过程结果的提示,并提供有助于任何后续编辑操作的提示。这是通过发出带有适当提示的closeEditor()信号来实现的。这是由构建spin box时安装的默认QStyledItemDelegate事件过滤器来处理的。
可以调整数字设定框的行为,使其更便于用户使用。在QStyledItemDelegate提供的默认事件过滤器中,如果用户点击Return确认他们在数字设定框中的选择,则代理将值提交给模型并关闭数字设定框。我们可以通过在数字设定框上安装自己的事件过滤器来改变这种行为,并提供适合我们需求的编辑提示;例如,我们可能会发出带有EditNextItem提示的closeEditor(),以自动开始编辑视图中的下一个项目。
另一种不需要使用事件过滤器的方法是提供我们自己的编辑器小部件,为了方便起见,可能会对QSpinBox进行子类化。这种替代方法将使我们能够以编写额外代码为代价,更好地控制编辑器小部件的行为。如果需要自定义标准Qt编辑器小部件的行为,通常在委托中安装事件过滤器会更容易。
委托不必发出这些提示,但那些没有发出提示的委托将较少地集成到应用程序中,并且将比那些发出提示以支持常见编辑操作的委托更难使用。

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

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

相关文章

【C语言零基础入门篇 - 7】:拆解函数的奥秘:定义、声明、变量,传递须知,嵌套玩转,递归惊艳

文章目录 函数函数的定义与声明局部变量和全局变量、静态变量静态变量和动态变量函数的值传递函数参数的地址传值 函数的嵌套使用函数的递归调用 函数 函数的定义与声明 函数的概念&#xff1a;函数是C语言项目的基本组成单位。实现一个功能可以封装一个函数来实现。定义函数的…

DPDK 简易应用开发之路 3:实现ping(ARP ICMP 协议)

本机环境为 Ubuntu20.04 &#xff0c;dpdk-stable-20.11.10 网卡IP为192.168.131.153 mac地址 00 0c 29 00 04 4d 理论基础 机器A内部没有机器B的物理地址&#xff0c;则 A ping B 的时候需要先发 arp 请求&#xff0c;以获取机器 B 的 MAC 地址。 获取 MAC 地址 如果 A 和 …

python画图1

import matplotlib.pyplot as pltplt.rcParams["font.sans-serif"] ["SimHei"]# 模拟数据 years [2016, 2017, 2018, 2019, 2020, 2021, 2022] market_size [7950, 8931, 9940, 11205, 12305, 13199, 14980] my_color #3e9df5plt.plot(years, market_s…

ER论文阅读-Decoupled Multimodal Distilling for Emotion Recognition

基本介绍&#xff1a;CVPR, 2023, CCF-A 原文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2023/papers/Li_Decoupled_Multimodal_Distilling_for_Emotion_Recognition_CVPR_2023_paper.pdf Abstract 多模态情感识别&#xff08;MER&#xff09;旨在通过语言、…

spring-boot-maven-plugin插件打包和java -jar命令执行原理

文章目录 1. Maven生命周期2. jar包结构2.1 不可执jar包结构2.2 可执行jar包结构 3. spring-boot-maven-plugin插件打包4. 执行jar原理 1. Maven生命周期 Maven的生命周期有三种&#xff1a; clean&#xff1a;清除项目构建数据&#xff0c;较为简单&#xff0c;不深入探讨&a…

面试速通宝典——1

1. 内存有哪几种类型&#xff1f; ‌‌‌‌  内存分为五个区&#xff0c;堆&#xff08;malloc&#xff09;、栈&#xff08;如局部变量、函数参数&#xff09;、程序代码区&#xff08;存放二进制代码&#xff09;、全局/静态存储区&#xff08;全局变量、static变量&#…

Gitlab学习(008 gitlab开发工作流GitFlow)

尚硅谷2024最新Git企业实战教程&#xff0c;全方位学习git与gitlab 总时长 5:42:00 共40P 此文章包含第27p-第p29的内容 文章目录 工作流分类集中式工作流功能开发工作流GitFlow工作流Forking工作流 各个分支的功能模拟工作环境创建分支登录领导&#xff08;项目管理者&#…

idea插件开发的第五天-今天不写工具

介绍 今天介绍一款插件,可以帮你调用spring容器里面的方法,并且可以执行脚本 Demo说明 本文基于maven项目开发,idea版本为2022.3以上,jdk为1.8本文在Tools插件之上进行开发本次demo将使用idea的一些组件优化 Tools插件说明 Tools插件是一个Idea插件,此插件提供统一Spi规范…

Linux自主学习篇

用户及权限管理 sudo 是 "superuser do" 的缩写&#xff0c;是一个在类 Unix 操作系统&#xff08;如 Linux 和 macOS&#xff09;中使用的命令。它允许普通用户以超级用户&#xff08;root 用户&#xff09;的身份执行命令&#xff0c;从而获得更高的权限。 useradd…

学生管理系统1.0版本

学生管理系统1.0版本有5个功能&#xff0c;即添加学生、删除学生、修改学生、查看全部学生、退出系统。 里面对添加重复学号、删除和修改不存在的学号等问题都有相应的解决办法。 代码区&#xff1a; Student.java package student;//快捷键Altinsert public class Student …

【中国留学网-注册_登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

来!一起探索 2024 年数据和 AI 的奇妙世界

来&#xff01;一起探索 2024 年数据和 AI 的奇妙世界 前言2024 年数据和 AI 的奇妙世界 前言 生成式 AI 的问世&#xff0c;让世界正在经历一场前所未有的变革&#xff0c;就像是一把神奇的钥匙&#xff0c;正在开启一扇通往无限可能的大门。数据和 AI 的融合&#xff0c;将为…

微服务注册中⼼1

1. 微服务的注册中⼼ 注册中⼼可以说是微服务架构中的”通讯录“ &#xff0c;它记录了服务和服务地址的映射关系。在分布式架构中&#xff0c; 服务会注册到这⾥&#xff0c;当服务需要调⽤其它服务时&#xff0c;就这⾥找到服务的地址&#xff0c;进⾏调⽤。 1.1 注册中⼼的…

算法之逻辑斯蒂回归(Logistic regression)

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 逻辑斯蒂回归&#xff08;Logistic Regression&#xff09;是统计学中一种广泛应用于二分类问题的算法。它的主要目标是预测二分类问题中的事件发生的概率。尽管名字里有“回归”&#xff0c;但逻…

全栈项目小组【算法赛】题目及解题

题目&#xff1a;全栈项目小组【算法赛】 题目&#xff1a; 解题思路 1.遍历简历信息&#xff1a;我们需要读取所有简历&#xff0c;根据期望薪资和岗位类型进行分类和统计。 2.分类统计&#xff1a;使用哈希表来存储每个薪资下的前端&#xff08;F&#xff09;和后端&#…

re题(38)BUUCTF-[FlareOn6]Overlong

BUUCTF在线评测 (buuoj.cn) 运行一下.exe文件 查壳是32位的文件&#xff0c;放到ida反汇编 对unk_402008前28位进行一个操作&#xff0c;我们看到运行.exe文件的窗口正好是28个字符&#xff0c;而unk_402008中不止28个数据&#xff0c;所以猜测MessageBoxA&#xff08;&#x…

《论软件架构建模技术与应用》写作框架,软考高级系统架构设计师

论文真题 软件架构风格是描述一类特定应用领域中系统组织方式的惯用模式&#xff0c;反映了领域中诸多系统所共有的结构特征和语义特征&#xff0c;并指导如何将各个模块和子系统有效组织成一个完整的系统。分层架构是一种常见的软件架构风格&#xff0c;能够有效简化设计&…

0基础跟德姆(dom)一起学AI 数据处理和统计分析07-分组和会员数据分析

向量化函数及Lambda表达式 * 分组操作相关 * 分组聚合 * 分组转换 * 分组过滤 * DataFrameGroupBy对象介绍 * 会员分析案例-数据透视表 --- 1.向量化函数 * 分析代码 python def avg_test2(x,y): if x20: return np.NaN else: retu…

[杂谈-黑神话:悟空] 中国3A游戏的崛起之路:挑战与机遇并存

[杂谈-黑神话:悟空] 中国3A游戏的崛起之路&#xff1a;挑战与机遇并存 《黑神话&#xff1a;悟空》的出现&#xff0c;让我们看到了中国3A游戏的希望和未来。对于中国游戏产业的从业者和爱好者来说&#xff0c;这是一个值得关注和期待的领域。 在游戏产业蓬勃发展的今天&#…

Java之线程篇六

目录 CAS CAS伪代码 CAS的应用 实现原子类 实现自旋锁 CAS的ABA问题 ABA问题导致BUG的例子 相关面试题 synchronized原理 synchronized特性 加锁过程 相关面试题 Callable 相关面试题 JUC的常见类 ReentrantLock ReentrantLock 和 synchronized 的区别: 原…