【Qt】【模型视图架构】 在项目视图中启用拖放
文章目录
- 1. 在便捷类中启用拖放
- 2. 在模型/视图类中启用拖放
模型/视图框架支持Qt的拖放应用。
列表、表格和树中的项目可以在视图中被拖拽,数据作为MIME编码的数据被导入和导出。标准视图可以自动支持内部的拖放。
默认视图的拖放功能并没有被启用,如果要进行项目的拖动,就需要进行一些属性的设置。
如果在一个新的模型中启用拖放功能,还需要重新实现一些函数。
1. 在便捷类中启用拖放
三个便捷类QListWidget、QTreeWidget、QTableWidget中每一种类型的项目都默认配置了一组不同的标志。
每一个QListWidgetItem和QTreeWidgetItem被初始化为可用的、可检查的、可选择的,也可以用作拖放的源。每一个QTableWidgetItem可以被编辑和用作拖放操作的目标。
一般还需要在视图中设置一些属性来使它启用对拖放操作的内建支持:
- 启用项目拖拽,需要将视图的
dragEnable属性设置为true; - 要允许用户将内部或者外部的项目放入视图中,需要设置视图的视口
viewport()的acceptDrops属性为true; - 要显示现在用户拖拽的项目将要被放置的位置,需要设置
showDropIndicator属性;
如下:
////// 在视图项目中启用拖放功能///listWidget.setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); // 设置单选模式listWidget.setDragEnabled(true); // 启用拖拽listWidget.viewport()->setAcceptDrops(true); // 设置接受拖放listWidget.setDropIndicatorShown(true); // 设置显示将要被放置的位置listWidget.setDragDropMode(QListWidget::InternalMove); // 设置拖放模式为移动项目,如果不设置,默认为复制项目treeWidget.setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); // 设置单选模式treeWidget.setDragEnabled(true); // 启用拖拽treeWidget.viewport()->setAcceptDrops(true); // 设置接受拖放treeWidget.setDropIndicatorShown(true); // 设置显示将要被放置的位置treeWidget.setDragDropMode(QTreeWidget::InternalMove); // 设置拖放模式为移动项目,如果不设置,默认为复制项目tableWidget.setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); // 设置单选模式tableWidget.setDragEnabled(true); // 启用拖拽tableWidget.viewport()->setAcceptDrops(true); // 设置接受拖放tableWidget.setDropIndicatorShown(true); // 设置显示将要被放置的位置tableWidget.setDragDropMode(QTableWidget::InternalMove); // 设置拖放模式为移动项目,如果不设置,默认为复制项目
2. 在模型/视图类中启用拖放
在视图中启用拖放功能与在便捷类中的设置相似。如下:
////// 模型/视图中启用拖放功能///listView->setSelectionMode(QAbstractItemView::SingleSelection); // 设置单选模式listView->setDragEnabled(true); // 启用拖放功能listView->setAcceptDrops(true); // 接受拖放listView->setDropIndicatorShown(true); // 显示要被放置的位置
自定义模型中的flags()函数要提供对于拖放操作的支持,即需要增加Qt::ItemIsDragEnabled和Qt::ItemIsDropEnabled标志。
由于视图中显示的数据是由模型控制的,也要为使用的模型提供拖放操作的支持。需要重新实现一些必要的函数。如下:
// 设置支持的拖拽动作Qt::DropActions supportedDropActions() const override;// 设置在拖放操作中导出的条目的数据的编码类型QStringList mimeTypes() const override;// 将拖放的数据放入QMimeData中QMimeData *mimeData(const QModelIndexList &indexes) const override;// 将拖放操作的数据放入模型中bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
这些函数的实现代码如下:
/*设置支持使用拖放进行复制和移动两种操作*/
Qt::DropActions StringListModel::supportedDropActions() const
{return Qt::CopyAction | Qt::MoveAction; // 设置模型支持拖拽时的移动和复制操作/** 要允许Qt::MoveAction,模型需要实现removeRows()函数*/
}
/*在拖放操作中的数据项从模型中导出时,要被编码为合适的格式来对应一个或多个MIME类型,
如下自定义了一个类型,仅支持纯文本类型*/
QStringList StringListModel::mimeTypes() const
{QStringList types;// application/vnd.text.list为自定义的类型,后续需要保持一致types << "application/vnd.text.list";return types;
}
/*进行拖放操作之前,需要将数据放入到一个QMimeData类型的对象中,
如下使用自定义的格式,将所有要拖拽的数据都放入一个QMimeData对象中*/
QMimeData *StringListModel::mimeData(const QModelIndexList &indexes) const
{QMimeData *mimeData = new QMimeData;QByteArray encodedData;QDataStream stream(&encodedData, QDataStream::WriteOnly);//根据传入的indexes获取到所有的文本数据foreach (const QModelIndex &index, indexes) {if(index.isValid()){QString text = data(index, Qt::DisplayRole).toString();stream << text;}}// 将数据放入QMimeData中mimeData->setData("application/vnd.text.list", encodedData);return mimeData;
}bool StringListModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{// 如果是 Qt::IgnorAction,直接返回trueif(action == Qt::IgnoreAction)return true;// 如果数据不是指定的格式,返回falseif(!data->hasFormat("application/vnd.text.list"))return false;// 该模型是列表模型,只有一列,判断列是否正确if(column>0)return false;// 设置开始插入的行int beginRow=0;if(row != -1)beginRow = row;else if(parent.isValid())beginRow = parent.row();elsebeginRow = rowCount(QModelIndex());// 从data中读取数据QByteArray encodedData = data->data("application/vnd.text.list");QDataStream stream(&encodedData, QDataStream::ReadOnly);QStringList newItem;int rows=0;while (!stream.atEnd()) {QString text;stream >> text;newItem << text;++rows;}insertRows(beginRow, rows, QModelIndex());foreach (const QString &text, newItem) {QModelIndex idx = index(beginRow, 0, QModelIndex());setData(idx, text);beginRow++;}return true;
}
任何给定的模型处理放入数据的方式都依赖于它们的类型和向用户展现的方式。
一般应该使用最适合模型底层数据存储的方式来容纳放入的数据。不同类型的模型会使用不同的方式来处理放入的数据。
列表和表格模型只提供了一个平面结构来存储数据项,结果是可能会在当数据放入一个视图中的已经存在的项目时插入新的行或列,或者会使用提供的数据来覆盖已经存在的项目的内容。
树模型一般会在底层数据存储中添加包含新的数据的子项。
最后还需要更新flags()函数,用于提供合适的标志向视图表明哪些项目是可以被拖拽的、哪些项目是可以接受放入的。
在自定义模型中实现视图中的项的拖放代码参考:https://github.com/Innern/Qt/tree/master/ModelView/Examples/01_AddressBooks,该项目参考了官方示例Address Books Example,但是增加了对视图中的项的拖放的支持。
如下:

需要注意的是:
- mimeData()函数的参数indexes包含所有选择拖放的项的索引。比如,
- 如果是简单的列表视图,只有一列,选择拖放时只选择了一行,那么indexes中包含一个索引,即这一行的索引。
- 如果是表格视图,有两列,选择拖放时选择一行,那么indexes中包含两个索引,即这一行的每一列的索引。
相关文章:
【Qt】【模型视图架构】 在项目视图中启用拖放
文章目录 1. 在便捷类中启用拖放2. 在模型/视图类中启用拖放 模型/视图框架支持Qt的拖放应用。 列表、表格和树中的项目可以在视图中被拖拽,数据作为MIME编码的数据被导入和导出。标准视图可以自动支持内部的拖放。 默认视图的拖放功能并没有被启用,如果…...
B端产品无爆款,说有的都是忽悠和外行!
前言:网上经常有人讲运营,把C端那一套硬搬到B端,讲的自我陶醉,稍微有点常识的人就知道不能这么玩。 一、什么是B端和C端 B端(Business-to-Business)是指面向企业客户的市场和产品。B端产品或服务主要是为…...
腾讯云的身份证核验,找不到这个类
文件上传功能在许多Web应用程序中是非常常见的需求之一。然而,由于文件上传存在安全风险,保护用户上传的文件的安全性,以及防止黑客利用上传功能进行攻击是非常重要的。在本文中,我们将讨论一些常见的安全漏洞,并提供一…...
vue3 vue-draggable-next 实现拖拽穿梭框效果
一、vue3 vue-draggable-next 实现拖拽穿梭框效果 <template> <div> <h2>列表 1</h2> <draggable v-model"list1" group"items" tag"transition-group" end"onDragEnd"> <div v-for"(item…...
FreeRTOS【16】直达任务通知使用
1.开发背景 直达任务通知,FreeRTOS 的线程任务提供的接口,可以用作线程唤醒,或者是传递数据,因为是基于线程本身的操作,是轻量级,速度响应更快,适合小内存芯片使用。 事实上本人使用得比较少&am…...
关于软件<PDF文档管理系统V1.0>的介绍
<PDF文档管理系统V1.0>(下载地址在最下面)是我在2023年发布的<知识辅助系统>的改善以及重新开发版本,软件在重新开发提供了<知识辅助系统>的所有功能的基础上,添加了一些新的功能。软件尽量提供简单、实用的功能…...
Java面试题-Tomcat初级面试题
Tomcat是什么?请简述它的主要功能。 Tomcat是一个开源的Web应用服务器,由Apache软件基金会开发。它是一个实现了Java Servlet和JavaServer Pages(JSP)技术的容器,用于处理客户端的请求并返回响应。Tomcat的主要功能如…...
红队内网攻防渗透:内网渗透之windows内网权限提升技术:数据库篇
红队内网攻防渗透 1. 内网权限提升技术1.1 数据库权限提升技术1.1.1 数据库提权流程1.1.1.1 先获取到数据库用户密码1.1.1.2 利用数据库提权工具进行连接1.1.1.3 利用建立代理解决不支持外联1.1.1.4 利用数据库提权的条件及技术1.1.2 Web到Win-数据库提权-MSSQL1.1.3 Web到Win-…...
rust嵌入式开发之总结
我们用rust开发的新版产品刚刚交付,已经在海上安装测试完毕并顺利投产。终于松了口气,同时也有时间和精力来做个全面的总结了。 这个产品,目前差不多有三版: 第一个版本是用crt-thread写的,投产后出了一个内存泄露的…...
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版6(附带项目源码)
最终效果 系列导航 文章目录 最终效果系列导航前言方法一、使用excel配置表excel转txt文本读取txt数据按配置信息生成僵尸 方法二、使用ScriptableObject 配置关卡信息源码结束语 前言 本节主要是推荐两种实现配置关卡信息,并按表生成僵尸和关卡波次 方法一、使用…...
回溯算法指组合总和
题目: 找出所有相加之和为 n 的 k 个数的组合,且满足下列条件: 只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。 思路: 这种问题…...
java-stream转换map key重复报错解决小记
解决key重复问题 在用stream转成map过程中会有key重复的隐患,如果数据没重复还好,如果重复了会提示 java.lang.IllegalStateException: Duplicate key 8753444332651at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)at ja…...
王春城 | 如何解决精益转型过程中的信任问题?
实践证明,精益转型不仅仅是技术和管理方法的更新,更是一场深刻的文化变革。在这个过程中,涉及到多个部门、多个层级的协同合作,需要团队成员之间的深度沟通和高度信任。如果缺乏信任,团队成员之间就会产生隔阂和抵触情…...
Ubuntu Nvidia Docker单机多卡环境配置
ubuntu版本是22.04,现在最新版本是24.xx,截止当前,Nvidia的驱动最高还是22.04版本,不建议更新至最新版本。本部分是从0开始安装Nvidia docker的记录,若已安装Nvdia驱动,请直接跳至3。 1、更新软件软件列表…...
小公司的软件开发IT工具箱
目录 工具链困境 难题的解决 达到的效果 资源要求低 工具箱一览 1、代码管理工具 2、自动化发版(测试)工具 3、依赖库(制品包)管理 4、镜像管理 5、授权管理(可选) 待讨论:为什么不是…...
代码随想录算法训练营第四十四天| 背包问题、背包问题之滚动数组、416. 分割等和子集
背包问题 题目链接:背包问题 文档讲解:代码随想录/背包问题 视频讲解:视频讲解-背包问题 状态:已完成(1遍) 解题过程 这几天属实是有点分身乏术了,先直接看题解AC了,二刷的时候再…...
最新一站式AI创作中文系统网站源码+系统部署+支持GPT对话、Midjourney绘画、Suno音乐、GPT-4o文档分析等大模型
一、系统简介 本文将介绍最新的一站式AI创作中文系统(集成ChatGPTMidjourneySunoStable Diffusion)——星河易创AI系统,该系统基于ChatGPT的核心技术,融合了自然语言问答、绘画、音乐、文档分享、图片识别等创作功能,…...
C# 语言类型(二)—预定义类型之字符串及字符类型简述
总目录 C# 语法总目录 参考链接: C#语法系列:C# 语言类型(一)—预定义类型值之数值类型 C#语法系列:C# 语言类型(二)—预定义类型之字符串及字符类型简述 C#语法系列:C# 语言类型(三)—数组/枚举类型/结构体 C#语法系列:C# 语言类型(四)—传递参数及其修饰符 C#语法…...
微信小程序canvas画图使用百分比适配不同机型屏幕达到任何屏幕比例皆可!完美适配任何机型!指定canvas尺寸适配亦可!保证全网唯一完美
错误代码示例: // 在onLoad中调用 const that this wx.getSystemInfo({success: function (res) {console.log(res)that.setData({model: res.model,screen_width: res.windowWidth/375,screen_height: res.windowHeight})} }) 我看到网上很多使用上面这种代码去…...
Redis-02
redis安装包位置 /opt/redis-7.2.5 redis默认安装路径: 配置文件路径:/usr/local/bin/redisconfig gcc安装位置 /opt/rhredis启动: 在/usr/local/bin目录下输入redis-server redisconfig/redis.confredis-cli -p 6379redis性能测试命令 red…...
OpenClaw+千问3.5-9B智能家居:自然语言控制HomeAssistant
OpenClaw千问3.5-9B智能家居:自然语言控制HomeAssistant 1. 为什么需要自然语言控制智能家居? 去年装修新房时,我安装了HomeAssistant系统来控制全屋灯光、空调和窗帘。虽然手机App能实现远程控制,但每次都要打开应用、找到对应…...
光流法在气象雷达中的应用:从原理到外推实践
光流法在气象雷达中的应用:从原理到外推实践 气象雷达作为现代气象监测的核心工具,其回波数据蕴含着丰富的天气系统动态信息。如何从这些看似静态的图像序列中提取运动规律,进而预测未来短时内的天气变化,一直是气象学界和工程界关…...
别再死记参数了!深入Halcon measure_pos算子底层:从高斯滤波到亚像素边缘的完整推导
深入解析Halcon measure_pos算子:从数学原理到工程调优 在工业视觉检测领域,亚像素级边缘检测一直是核心难题。当我们使用Halcon这类专业工具时,measure_pos算子看似简单易用,但真正理解其底层机制的人却寥寥无几。本文将带您穿透…...
DeOldify开发者效率提升:10分钟集成到现有Flask/Django项目中
DeOldify开发者效率提升:10分钟集成到现有Flask/Django项目中 1. 项目简介 你是不是遇到过这样的场景:客户想要一个黑白照片上色的功能,但你完全不懂深度学习?或者想要给老照片修复应用添加AI能力,却被复杂的模型部署…...
INNISO1接口模块
INNIS01 接口模块INNIS01 是一款应用于工业自动化控制系统中的接口模块,主要用于实现控制系统内部或与外部设备之间的信号连接与数据交互,属于系统中的通信与接口扩展单元。一、基本概述INNIS01 接口模块通常用于连接控制器与现场设备或其他功能模块&…...
微型LORA数传模块:科技赋能,传统楼宇智能蜕变
微型LoRa数传模块凭借小体积、低功耗、远距离、强穿透、易部署的核心优势,是智慧楼宇实现无线化、低成本、广覆盖物联网感知与控制的理想选择,尤其适合老旧楼宇改造与新建楼宇的轻量化智能化升级。一、核心优势(适配智慧楼宇场景)小体积易安装࿱…...
音乐留学路上,这些坑我替你踩过了|纯干货分享
写给正在准备或即将踏上音乐留学之路的你嘿,准备音乐留学的你。我知道你现在可能既兴奋又焦虑,手里攥着梦想,却不知道下一步该往哪走。别慌,作为过来人,我想跟你聊点实在的。"音乐留学不是终点,而是你…...
Cursor Pro完整解锁方案:一站式解决AI编程助手使用限制的终极指南
Cursor Pro完整解锁方案:一站式解决AI编程助手使用限制的终极指南 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reach…...
Spring Boot项目实战:用ShardingSphere-JDBC 5.3.2搞定PostgreSQL分库分表,附完整配置流程
Spring Boot与ShardingSphere-JDBC深度整合:PostgreSQL分库分表实战指南 当你的应用用户量突破百万级,单表数据量超过千万行时,是否经常遇到查询响应变慢、写入性能下降的问题?作为经历过多次系统扩容的老兵,我想分享一…...
clusterProfiler进阶指南:如何利用R语言进行多组学数据的功能富集分析与可视化
clusterProfiler进阶指南:如何利用R语言进行多组学数据的功能富集分析与可视化 在生物信息学领域,功能富集分析是将高通量组学数据转化为生物学洞见的关键步骤。作为R/Bioconductor生态中的明星工具,clusterProfiler以其强大的分析能力和丰富…...
