【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::ItemIsDragEnabledQt::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,但是增加了对视图中的项的拖放的支持。

如下:

在这里插入图片描述

需要注意的是:

  1. mimeData()函数的参数indexes包含所有选择拖放的项的索引。比如,
    1. 如果是简单的列表视图,只有一列,选择拖放时只选择了一行,那么indexes中包含一个索引,即这一行的索引。
    2. 如果是表格视图,有两列,选择拖放时选择一行,那么indexes中包含两个索引,即这一行的每一列的索引。

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

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

相关文章

opencv进阶 ——(八)图像处理之RMBG模型AI抠图

BRIA.AI团队于HuggingFace开源了一个基于ISNet背景移除模型RMBG-1.4&#xff0c;它可以有效对前景与背景进行分离。RMBG-1.4在精心构建的数据集上训练而来&#xff0c;该数据包含常规图像、电商、游戏以及广告内容&#xff0c;该方案达到了商业级性能&#xff0c;但仅限于非商业…

【PHP项目实战训练】——laravel框架的实战项目中可以做模板的增删查改功能(1)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

【管理咨询宝藏120】顶级咨询公司领导管控优化设计方案

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏120】顶级咨询公司领导管控优化设计方案 【格式】PDF版本 【关键词】人力资源、组织管控、领导力 【核心观点】 - 管的过细” “高层的管理要往…

【排序】冒泡排序

在我们的生活中&#xff0c;到处都离不开排序的作用&#xff0c;考试分数要排序&#xff0c;商场购物要排序&#xff0c;可以说排序对我们来说处处存在&#xff0c;那么从本章开始&#xff0c;我将要依次分享一些排序方法&#xff0c;从易到难&#xff0c;包括冒泡&#xff0c;…

随身wifi和手机流量卡,你知道该怎么选吗?

网络已经成为我们这个时代的代名词&#xff01; 那么&#xff0c;在上网的时代&#xff0c;我们有很多问题都要考虑&#xff0c;比如如何选择上网方式&#xff0c;是选择一张流量卡&#xff0c;还是一个随身WIFI&#xff1f; 听小编一句劝&#xff0c;先不要着急买&#xff0c…

接口测试工具:Postman的下载安装及使用

1 Postman 介绍 1.1 Postman 是什么 Postman 是一款功能超级强大的用于发送 HTTP 请求的 测试工具 做 WEB 页面开发和测试的人员常用工具 创建和发送任何的 HTTP 请求(Get/Post/Put/Delete...) 1.2 Postman 相关资源 1.2.1 官方网站&#xff1a;https://www.postman.com/ …

sde the Upgrade Geodatabase tool to install/upgrade system tables (-64).

数据库端迁移sde导入后&#xff0c;在sde端启动服务报错&#xff1a; ------------------------------------------------------- ArcSDE 10.0 for Oracle11g Build 685 Fri May 14 12:05:43 2010 ------------------------------------------------------- ST_Geometry Sc…

Java——面向对象初阶

前言&#xff1a; Java面向对象相关讲解 文章目录 一、面向对象二、类与对象三、封装四、构造方法及重载五、this关键字六、基本数据类型和引用数据类型七、JavaBean类 一、面向对象 面向对象&#xff08;Object-Oriented Programming, OOP&#xff09;是一种编程范式&#xff…

C++第二十二弹---vector深度剖析及模拟实现(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、容量操作 2、内容修改操作 3、打印函数 4、迭代器失效 4.1、什么是迭代器失效 4.2、哪些操作会引起迭代器失效 总结 1、容量操作 size()…

Idea的相关操作

1、关闭自动更新 点击左上角File->Setting&#xff0c;进入配置页面&#xff0c;点击Appearance & Behavior > System Settings > Updates&#xff0c;取消勾选更新选项&#xff0c;如图&#xff1b; 2、代码提示忽略大小写 点击左上角File->Setting&#xf…

用Unityhub安装unity2018.3.0和vuforia

打开下载网址 https://unity.cn/releases/full/2018 选择2018.3.x 找到2018.3.0后&#xff0c;点击从UnityHub下载 然后unityhub会弹出安装界面 只勾选这两个&#xff0c;其余的全部取消勾选&#xff0c;默认勾选上的也取消掉&#xff0c;然后点击安装

【数据分享】2009-2022年我国省份级别的轨道交通相关指标(20多项指标)

《中国城市建设统计年鉴》中细致地统计了我国城市市政公用设施建设与发展情况&#xff0c;在之前的文章中&#xff0c;我们分享过基于2006-2022年《中国城市建设统计年鉴》整理的2006—2022年我国省份级别的市政设施水平相关指标、2006-2022年我国省份级别的各类建设用地面积数…

String 类

目录&#xff1a; 一. 认识 String 类 二. String 类的基本用法 三. String对象的比较 四.字符串的不可变性 五. 认识 StringBuffer 和 StringBuilder 一. 认识 String 类&#xff1a; 在C语言中已经涉及到字符串了&#xff0c;但是在C语言中要表示字符串只能使用字符数组或者…

Unity2D横版摄像机跟随

在Unity2D横版游戏中&#xff0c;摄像机跟随是一个非常重要的功能。一个流畅的摄像机跟随系统可以让玩家更好地沉浸在游戏世界中。本文将介绍如何在Unity中实现2D横版摄像机跟随&#xff0c;并分享一些优化技巧。 一、准备工作 在开始实现摄像机跟随之前&#xff0c;请确保您…

MFC 模态对话框的实现原理

参考自MFC 模态对话框的实现原理 - 西昆仑 - OSCHINA - 中文开源技术交流社区 1. 模态对话框 在涉及 GUI 程序开发的过程中&#xff0c;常常有模态对话框以及非模态对话框的概念 模态对话框&#xff1a;在模态对话框活动期间&#xff0c;父窗口是无法进行消息响应&#xff0…

JavaEE初阶多线程 (5)

1.锁的策略 1.1锁的策略是什么 这个锁的策略可以理解为&#xff0c;一种做法&#xff0c;相当于当你遇到锁竞争&#xff0c;加锁解锁&#xff0c;的情况你会怎么做。 乐观锁可以理解为疫情的时候比较乐观就买了最基本的物资&#xff0c; 买的时候非常方便 1.2乐观锁 当效率…

Wireshark抓包后的报文太大,如何拆分?

背景&#xff1a;抓包获取到一个400多兆的网络数据包.pcapng文件&#xff0c;使用wireshark软件可以正常打开。但需要把文件导出为.json文件&#xff0c;从而方便对报文内容做过滤分析。使用wireshark自带的导出功能导出后发现生成的.json文件大小为2G多&#xff0c;使用notepa…

Python实现定时任务的方式

大家好&#xff0c;在当今数字化的时代&#xff0c;定时任务的需求在各种应用场景中频繁出现。无论是数据的定时更新、周期性的任务执行&#xff0c;还是特定时间点的操作触发&#xff0c;Python 都为我们提供了强大而灵活的手段来实现这些定时任务。当我们深入探索 Python 的世…

【机器学习】AI大模型的探索—浅谈ChatGPT及其工作原理

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 &#x1f4da;介绍ChatGPT 1.1 什么是ChatGPT 1.2 ChatGPT的应用场景 &#x1f4a1;基础概念 1. 人工智能和机器学习 1.1 人工智能&#xff08;AI&#xff09;简介 1.2 机器学习&#xff08;ML&#xff09;简…

【面结构光三维重建】0.基于openCV实现相机的标定

1.标定结果 2.相机标定原理 相机标定是计算机视觉和机器视觉领域中的重要技术,用于确定相机成像的几何关系和畸变特性,以提高成像的精度和稳定性。该技术广泛应用于三维重建、机器人视觉、自动驾驶等领域。 世界坐标系:由用户定义的三维世界坐标系,描述物体和相机在真实世…