【Qt之QSqlRelationalDelegate】描述及使用

描述

QSqlRelationalDelegate类提供了一个委托,用于显示和编辑来自QSqlRelationalTableModel的数据。

与默认委托不同,QSqlRelationalDelegate为作为其他表的外键的字段提供了一个组合框。
要使用该类,只需在带有QSqlRelationalDelegate实例的视图上调用QAbstractItemView::setItemDelegate();
Ex:

    QSqlRelationalTableModel* pModel = new QSqlRelationalTableModel();pModel->setTable("person");pModel->setRelation(2, QSqlRelation("items", "id", "itemtype"));ui->tableView->setModel(pModel);ui->tableView->setItemDelegate(new QSqlRelationalDelegate());pModel->select();

关系表模型示例(如下所示)演示了如何将QSqlRelationalDelegateQSqlRelationalTableModel结合使用,为表提供外键支持。
在这里插入图片描述

重写

有两个重写方法:

  1. QWidget *QSqlRelationalDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
  2. void QSqlRelationalDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
createEditor
QWidget *createEditor(QWidget *aParent,const QStyleOptionViewItem &option,const QModelIndex &index) const
{const QSqlRelationalTableModel *sqlModel = qobject_cast<const QSqlRelationalTableModel *>(index.model());QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;if (!childModel)return QItemDelegate::createEditor(aParent, option, index);QComboBox *combo = new QComboBox(aParent);combo->setModel(childModel);combo->setModelColumn(childModel->fieldIndex(sqlModel->relation(index.column()).displayColumn()));combo->installEventFilter(const_cast<QSqlRelationalDelegate *>(this));return combo;
}
  • 上述代码实现了自定义委托的createEditor函数,用于创建一个QComboBox作为单元格的编辑器
  • 通过index.model()获取主数据模型,并将其qobject_cast转换为QSqlRelationalTableModel类型(如果成功转换,则说明该数据模型具有关联模型)
  • 使用sqlModel->relationModel(index.column())获取与该列关联的子数据模型。如果该列没有关联模型,它将返回0,这意味着将使用默认的委托(QItemDelegate)来创建单元格编辑器。

如果存在关联模型,则创建一个QComboBox,并将其设置为该列的单元格编辑器。

  • 子模型是通过combo->setModel(childModel)设置的,其中childModel是通过sqlModel->relationModel(index.column())获取的
  • 使用sqlModel->relation(index.column()).displayColumn()获取子模型中用于显示选择项的列,并将其设置为QComboBox的模型列,即combo->setModelColumn
  • ComboBox安装一个事件过滤器,使得在编辑完成后能够正确更新主数据模型
  • 最后,返回ComboBox作为单元格编辑器。
setModelData
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{if (!index.isValid())return;QSqlRelationalTableModel *sqlModel = qobject_cast<QSqlRelationalTableModel *>(model);QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;QComboBox *combo = qobject_cast<QComboBox *>(editor);if (!sqlModel || !childModel || !combo) {QItemDelegate::setModelData(editor, model, index);return;}int currentItem = combo->currentIndex();int childColIndex = childModel->fieldIndex(sqlModel->relation(index.column()).displayColumn());int childEditIndex = childModel->fieldIndex(sqlModel->relation(index.column()).indexColumn());sqlModel->setData(index,childModel->data(childModel->index(currentItem, childColIndex), Qt::DisplayRole),Qt::DisplayRole);sqlModel->setData(index,childModel->data(childModel->index(currentItem, childEditIndex), Qt::EditRole),Qt::EditRole);
}
  • 上述代码实现了自定义委托的setModelData函数,用于将编辑器中的数据更新到主数据模型中
  • 首先,检查index是否有效,如果无效,则直接返回
  • 通过qobject_cast将数据模型转换为QSqlRelationalTableModel类型,并使用index.column()获取正在编辑的列的索引
  • 通过sqlModel->relationModel(index.column())获取与该列关联的子数据模型,如果该列没有关联模型,则将其设置为0
  • 通过qobject_cast将编辑器转换为QComboBox类型,并检查它们是否存在。如果不存在,则说明该列没有关联子模型或者使用默认委托编辑器,就调用默认委托的setModelData函数来更新数据模型,然后返回。

如果存在关联子模型和ComboBox编辑器,它就使用combo->currentIndex()获取当前ComboBox选中项的索引,使用sqlModel->setData将选中项的值设置到主数据模型的index位置。这里使用了两次sqlModel->setData,分别将选中项的“显示值”和“编辑值”设置到主数据模型中,其中“显示值”是通过sqlModel->relation(index.column()).displayColumn()获取的子模型中的列数据,而“编辑值”是通过sqlModel->relation(index.column()).indexColumn()获取的子模型中指定的列数据

  • 最后,完成了所有数据更新操作

注意

如果需要下拉框功能,就直接用就行。
先进行自定义信号发送,则需要子类化操作。

结论

记住,你是最好的!如果有人比你好,那就假装没看见他们

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

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

相关文章

macbook电脑运行缓慢和卡顿内存怎么清理了?

假如你还在为“你的系统内存不足”的提示所困扰&#xff0c;或者你的Mac电脑突然运行缓慢和卡顿&#xff0c;那么你一般需要认真了解一下macbook内存怎么清理了? MacBook是功能强大的电脑&#xff0c;这点毫无疑问&#xff0c;但是它仍旧会随着时间推移变得运行缓慢。值得庆幸…

linux下恶意软件的七种反分析技术

7 类主流的 Linux 恶意软件反分析/检测躲避技术 反调试&#xff08;Anti-Debug&#xff09;: 软件调试是恶意软件分析的常⽤⼿段之⼀&#xff0c;但恶意软件可以通过识别调试器特征&#xff0c;实现⾃⾝恶意⾏为的隐藏&#xff0c;或导致调试失败&#xff0c;从⽽规避分析与检测…

二叉树OJ题之二

今天我们一起来看一道判断一棵树是否为对称二叉树的题&#xff0c;力扣101题&#xff0c; https://leetcode.cn/problems/symmetric-tree/ 我们首先先来分析这道题&#xff0c;要判断这道题是否对称&#xff0c;我们首先需要判断的是这颗树根节点的左右子树是否对称&#xff0…

VSCODE+QEMU+WSL调试RISCV代码(SBI、kernel)

前言 最近在对RISC-V架构比较感兴趣&#xff0c;正好手头有《RISC-V体系结构编程与实践》的书籍&#xff0c;就打算跟随笨叔将这块的知识学习起来&#xff0c;最开始当然是需要搭建一个基础的实验平台&#xff0c;本来笨叔是贴心的提供了VMare的环境&#xff0c;奈何天生叛逆的…

消息中间件——RabbitMQ(七)高级特性 2

前言 上一篇消息中间件——RabbitMQ&#xff08;七&#xff09;高级特性 1中我们介绍了消息如何保障100%的投递成功&#xff1f;,幂等性概念详解,在海量订单产生的业务高峰期&#xff0c;如何避免消息的重复消费的问题&#xff1f;,Confirm确认消息、Return返回消息。这篇我们…

作为用户,推荐算法真的是最优解么?

前言 众所周知&#xff0c;随着互联网技术的发展&#xff0c;推荐算法也越来越普及。无论是购物网站、社交媒体平台还是在线影视平台&#xff0c;推荐算法已成为用户获取相关信息的主要途径。据悉&#xff0c;近期GitHub决定结合算法推荐&#xff0c;将“Following”和“For Yo…

uniapp打包ios有时间 uniapp打包次数

我们经常用的解决方案有,分包,将图片上传到服务器上,减少插件引入。但是还有一个方案好多刚入门uniapp的人都给忽略了,就是在源码视图中配置,开启分包优化。 1.分包 目前微信小程序可以分8个包,每个包的最大存储是2M,也就是说你文件总体的大小不能超过16M,每个包的大…

刷题学习记录

[SWPUCTF 2021 新生赛]sql 进入环境 查看源码&#xff0c;发现是get传参且参数为wllm fuzz测试&#xff0c;发现空格&#xff0c;&#xff0c;and被过滤了 同样的也可以用python脚本进行fuzz测试 import requests fuzz{length ,,handler,like,select,sleep,database,delete,h…

【MySQL】常用内置函数:数值函数 / 字符串函数 / 日期函数 / 其他函数

文章目录 数值函数round()&#xff1a;四舍五入ceiling()&#xff1a;上限函数floor()&#xff1a;地板函数abs()&#xff1a;计算绝对值rand()&#xff1a;生成0-1的随机浮点数 字符串函数length()&#xff1a;获取字符串中的字符数upper() / lower()&#xff1a;将字符串转化…

算法---定长子串中元音的最大数目

题目 给你字符串 s 和整数 k 。 请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。 英文中的 元音字母 为&#xff08;a, e, i, o, u&#xff09;。 示例 1&#xff1a; 输入&#xff1a;s “abciiidef”, k 3 输出&#xff1a;3 解释&#xff1a;…

ThinkPHP的方法接收json数据问题

第一次接触到前后端分离开发&#xff0c;需要在后端接收前端ajax提交的json数据&#xff0c;开发基于ThinkPHP3.2.3框架。于是一开始习惯性的直接用I()方法接收到前端发送的json数据&#xff0c;然后用json_decode()解析发现结果为空&#xff01;但是打印出还未解析的值却打印得…

【代码随想录算法训练营-第一天】【数组】704. 二分查找、27. 移除元素

LeetCode-704.二分查找 【错误】第一遍提交的代码 主要错误点&#xff1a; 没弄清楚区间的定义导致&#xff1a;r 在定义处的赋值和 if 判断之后 r 的复制没有想清楚&#xff1b;没有搞清楚判断循环结束的条件&#xff1b;没有搞明白区间的定义&#xff0c;r 和 l 如何赋值&a…

使用Ray轻松进行Python分布式计算

大家好&#xff0c;在实际研究中&#xff0c;即使是具有多个CPU核心的单处理器计算机&#xff0c;也会给人一种能够同时运行多个任务的错觉。当我们拥有多个处理器时&#xff0c;就可以真正以并行的方式执行计算&#xff0c;本文将简要介绍Python分布式计算。 1.并行计算与分布…

MySQL事务日志

文章目录 1. redo日志 1. redo日志 口述&#xff1a;redo log 日志其实保证了ACID中的持久性&#xff0c;就是说当事务commit后&#xff0c;那么相应的修改呀更新这些操作其实都会记录到redo log中&#xff0c;其实这里的操作还是区别于redis中的aof中&#xff0c;它不是具体的…

文件中找TopK问题

目录 1.解题思路2.创建一个文件并在文件中写入数据3.为什么要建立小堆而不建立大堆&#xff1f;4.如何在现有的数据中建立适合的大堆&#xff1f;5.代码实现 1.解题思路 TopK问题即是在众多数据中找出前K大的值&#xff0c;则可以根据堆的性质来实现&#xff0c;但在使用堆之前…

Guacamole简介及centos7下搭建教程

简介 Guacamole是一款开源的远程桌面框架&#xff0c;它允许用户通过Web浏览器远程访问计算机资源。 官网地址&#xff1a;Apache Guacamole™ 官方文档&#xff1a;Installing Guacamole natively — Apache Guacamole Manual v1.5.3 架构 组件描述客户端浏览器用户通过支…

数据结构 / day02作业

1. 有若干个学校人员的信息,包括学生和教师。 其中学生的数据包括&#xff1a;姓名、性别、职业s/S、分数。 教师的数据包括:姓名、性别、职业t/T、职务。 1&#xff0c;定义指针指向堆区内存 2.循环输入 3.计算老师的个数 4.计算学生的平均值 5.循环输出 6释放堆区空间 #inc…

Jquery中的bind(),live(),delegate(),on()绑定事件方式

bind() 简要描述 bind()向匹配元素添加一个或多个事件处理器。 使用方式 $(selector).bind(event,data,function) event&#xff1a;必需项&#xff1b;添加到元素的一个或多个事件&#xff0c;例如 click,dblclick等&#xff1b; 单事件处理&#xff1a;例如 $(selector).bi…

不同类型的开源许可证

不同类型的开源许可证 什么是开源许可证 最简单的解释是&#xff0c;开源许可证是计算机软件和其他产品的许可证&#xff0c;允许在定义的条款和条件下使用、修改或共享源代码、蓝图或设计。开源并不意味着该软件可以根据需要使用、复制、修改和分发。根据开源许可证的类型&a…

gcp, loki, honeybadger 查看日志 语句

gcp, loki, honeybadger 查看日志 语句 GCP resource.type“cloudsql_database” AND logName:“projects/ebay-mag/logs/cloudsql.googleapis.com%2Fpostgres.log” AND ( textPayload:“[2823409]”) log_name“projects/ebay-mag/logs/cloudsql.googleapis.com%2Fpostgres…