QTreeView节点拖放

2023-05-16

拖放操作分为拖动(Drag)和放置(Drop)两种操作,当拖动时需要把拖动的数据进行存储(称为编码),数据存储为QMimeData类型的对象(称为放置数据),当执行放置操作时需要把存储的数据读取出来(称为解码),然后进行处理。

自定义拖放操作的步骤:

(1)启用视图拖放支持

ui->treeView->setDragEnabled(true); //允许拖放,默认未启用
ui->treeView->setAcceptDrops(true); //接受放置数据
ui->treeView->setDragDropMode(QAbstractItemView::InternalMove); //拖放模式为移动
ui->treeView->setDropIndicatorShown(true);  //显示拖放位置
ui->treeView->setDragDropOverwriteMode(true); //放下时覆盖已有项

(2)启用数据项的拖放支持

重新实现QAbstractItemModel::flags()函数以提供合适的标志来指示哪些项目可以被拖动,哪些项目将接受放置(Drop)。

(3)编码数据

重新实现QAbstractItemModel::mimeData()函数,把编码后的数据保存在该函数返回的QMimeData对象中。

(4)处理放置数据

重新实现QAbstractItemModel::dropMimeData()函数来处理放置数据,此时需要对放置数据进行解码(即读取出QMimeData对象存储的数据的内容),并将其插入模型的底层数据结构中(或进行其他处理),若该函数修改了数据项或模型的尺寸,则必须注意确保发出所有相关的信号。因为该函数需要插入或删除等操作,所以简单的调用QAbstractItemModel子类中的已经实现了的setData(),insertRows()和insertColumns()等函数会更方便。另外,还可以使用dropMimeData()函数的默认实现来处理放置数据,dropMimeData()函数的默认实现不会覆盖模型中的任何数据,它会将放置数据作为项目的同胞插入,或者作为该项目的子项插入。若要使用该函数的默认实现,就需要重新实现以下函数:insertRows()、insertColumns()、setData()、setItemData()。

示例如下:

//声明
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
Qt::DropActions supportedDropActions() const override;
virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
bool moveRows(QModelIndex sourceParent, int first, int last, QModelIndex destParent, int pos);


//实现
bool TreeModel::dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent)
{
	QByteArray array = data->data(QString("hehe"));
	QDataStream stream(&array, QIODevice::ReadOnly);
	qint64 p;
	stream >> p;
	QModelIndex* index = (QModelIndex*)p;
    /*
    此处存在一个坑,百度查资料查了很久,都解释说parent是放下时的节点的父节点索引,但我测试发现这个parent就是当前放下时的节点索引,所以在这里就当目标节点索引使用了
    */
	return moveRows(index->parent(), index->row(), index->row(), parent.parent(), parent.row());
}

Qt::DropActions TreeModel::supportedDropActions() const
{
	return Qt::MoveAction;
}

QMimeData * TreeModel::mimeData(const QModelIndexList & indexes) const
{
	QMimeData* mimeData = QAbstractItemModel::mimeData(indexes);
	//只取第一个
	for (int i = 0; i < indexes.count(); i++)
	{
		QModelIndex index = indexes[i];
		QModelIndex* p = new QModelIndex(index);
		TreeItem* item = static_cast<TreeItem*>(index.internalPointer());
		qDebug() << item->data(Qt::DisplayRole).toString();

		QByteArray array;
		QDataStream stream(&array, QIODevice::WriteOnly);
		stream << (qint64)p;
		mimeData->setData(QString("hehe"), array);
		return mimeData;
	}
	return mimeData;
}

bool TreeModel::moveRows(QModelIndex sourceParent, int first, int last, QModelIndex destParent, int pos)
{
	bool ret = false;
	if (!sourceParent.isValid() || !destParent.isValid())
		return ret;
	NetworkItem *srcItem = itemFromIndex(sourceParent);
	NetworkItem *destItem = itemFromIndex(destParent);

	if (beginMoveRows(sourceParent, first, last, destParent, pos))
	{
		if (destItem == srcItem)
		{
            //同级移动,即父节点相同
			ret = destItem->moveChildren(first, last, pos);
		}
		else
		{
			ret = destItem->moveChildren(srcItem, first, last, pos);
		}
		endMoveRows();
	}
	
	return ret;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QTreeView节点拖放 的相关文章

  • QT笔记- 设置QFileSystemModel在QTreeView中显示,显示指定目录及文件名或类型过滤

    示例 ui gt setupUi this model 61 new QFileSystemModel ui gt treeView 无论下面filter和view怎样设置 这条path上的文件夹都必显示 model gt setRootP
  • Qt笔记——QTreeView树状目录基本使用方法

    Qt自带了QTreeView控件用于树形菜单的展示 xff0c 记录基本的使用方法 一 在QT设计师中拖入一个QTreeView控件 二 代码 1 用model管理数据与视图的关系 QStandardItemModel model 61 n
  • QTreeView和QTreeWidget样式表的使用案例

    由于项目需要 xff0c 第一次接触到QT样式表 主要是修改QTreeWidget xff08 或者是QTreeView xff09 的界面问题 官方的帮助文档其实起到很大的作用 xff0c 网上的资料比较杂 xff0c 而且普遍描述得不清
  • QTreeView节点拖放

    拖放操作分为拖动 Drag 和放置 Drop 两种操作 xff0c 当拖动时需要把拖动的数据进行存储 称为编码 xff0c 数据存储为QMimeData类型的对象 称为放置数据 xff0c 当执行放置操作时需要把存储的数据读取出来 称为解码
  • Python:PyQt QTreeview 示例 - 选择

    我正在使用 Python 2 7 和 Qt 设计器 并且我是 MVC 新手 我在 Qt 中完成了一个视图 为我提供了目录树列表 以及用于运行事物的控制器 我的问题是 给定 Qtree 视图 选择目录后如何获取目录 代码快照如下 我怀疑它是
  • 如何扩展顶级QTreeview项目

    我不明白为什么这似乎没有扩展 QTreeView 中的顶级根项目 clear existing treeview data model self treeview model sourceModel model clear add tree
  • QT QItemSelectionModel 忽略列?

    我试图将树的选择限制为特定列 我大量使用委托来创建自定义的每项每列行为 编辑器等 我希望我可以通过阻止事件或类似的事情从委托中以某种方式完成此操作 问题是 我认为我必须创建一个完全自定义的解决方案来模仿扩展选择 然而 经过大量搜索和很少的示
  • qt:pyqt:QTreeView内部拖放几乎可以工作...拖动的项目消失

    I almost在 QTreeView 中具有完全有效的拖放重新排序功能 一切似乎都很好 除了掉落的物体永远不会出现 尽管我可以通过多种不同的方式引用它 向我证明它确实存在于它应该在的地方 如果有人有时间可以运行以下代码并让我知道我做错了什
  • 了解 Qt 视图模型架构:何时创建以及如何清理 QAbstractItemModel 实现中的索引?

    我目前正在将我的项目从QTreeWidget to QtreeView 并且有很多由于对Qt模型视图设计理解不佳而导致的问题 到目前为止 即使在 Qt 示例中我也找不到答案 我已经实现了我的QAbstractItemModel 我正在返回要
  • 何时从 QAbstractItemModel 发出 dataChanged

    在 Qt 中 我有一个模型子类化QAbstractItemModel 它是显示在 QTreeView 中的树 该模型支持各种形式的更改 并且都可以正常工作 相关的两个是 1 少量相关行中的部分数据发生变化 2 可视化更改意味着大多数行应更改
  • (PyQt) QTreeView - 想要展开/折叠所有子级和孙级

    我希望能够展开或折叠 QTreeView 中特定分支的所有子级 我正在使用 PyQt4 我知道 QTreeView 有一个绑定到 的展开所有子项功能 但我需要两件事 它需要绑定到不同的组合键 shift space 我还需要能够折叠所有子项
  • 我可以在aspx页面的page_load事件之前调用用户控件的page_load事件吗?

    问题很简单 我可以在aspx页面的page load之前调用usercontrol的page load吗 EDIT 不可能在父级的 page load 之前调用子级的 page load 事件 我有一个名为 just4test 的 aspx
  • QTreeView内存消耗

    我现在正在测试 QTreeView 功能 我对一件事感到惊讶 看来 QTreeView 内存消耗取决于项目计数 O O 这是非常不寻常的 因为这种类型的模型视图容器仅跟踪正在显示的项目 其余项目都在模型中 我用一个简单的模型编写了以下代码
  • 显示 QTreeView 的(可见)行数

    I found 这个问题 https stackoverflow com q 41634176 595305 and 这个问题 https stackoverflow com q 15817429 595305 我也在其他地方搜索过 情况是
  • QFileDialog 用于具有特定内容的目录

    我想建立一个类似于QFileDialog getExistingDirectory http doc qt nokia com 4 6 qfiledialog html getExistingDirectory仅当所选目录包含某些文件时才启
  • 在 QTreeView 中的文本之前显示图标

    I m using QtRuby with Qt 4 8 6 and trying to create a tree view where each item has a custom icon between the tree contr
  • QTreeView 中某些索引的自定义文本颜色

    我想使用自定义颜色 取决于与每行相关的数据 在 QTreeView 小部件的一列中绘制文本 我尝试重载 drawRow 受保护方法并更改样式选项参数 如下所示 一个精简示例 virtual void drawRow QPainter p p
  • 多级QTreeView

    我很难理解如何使用 QTreeView 和 QStandardItemModel 设置多级 QTree 这是我所拥有的 from PySide QtGui import import sys class MainFrame QWidget
  • QFileSystemModel setRootPath

    我正在尝试创建一个 Qt 应用程序来显示文件夹 Mac OS 中的 Users 文件夹 的内容 这是代码 QFileSystemModel dirModel new QFileSystemModel dirModel gt setRootP
  • QAbstractItemModel 如何表示树?

    我仍然很难理解 QAbstractItemModel 对项目的表示 有两种返回 QModelIndex 项的方法对我来说没有任何意义 QModelIndex QAbstractItemModel index int row int colu

随机推荐

  • 白话----之UCOS 信号量和邮箱

    总体理解 xff1a 两个任务需要共同访问一个共同的资源 xff0c 来切换或跳到不同的动作执行 这就产生信号量 两个任务 需要根据不同的按键选择 xff0c 来执行不同的动作 xff0c 产生邮箱 信号量和邮箱 我通过一个例子来学习的 希
  • 数据结构--结构体

    数据结构 https img blog csdn net 20181020104828701 watermark 2 text aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d4dWVjaGVuZw 61 61 font 5a
  • 小试牛刀爬北邮人论坛十大

    本来是为了写Alfred的work flow 不知道出了什么问题 一直都显示不了 sad 61 61 先把爬虫的代码贴这好了 好久没碰过python了 coding utf 8 author 61 39 wangxiao 39 import
  • mac安装homebrew报错 curl: (7) Failed to connect to raw.githubusercontent.com port443

    mac安装brew一直报错 xff0c 完整的报错信息如下 span class token literal property property curl span span class token operator span span c
  • C++ vector用法详解

    vector是STL的动态数组 xff0c 可以在运行中根据需要改变数组的大小 因为它以数组的形式储存 xff0c 所以它的内存空间是连续的 vector的头文件为 include lt vector gt 常用方法 xff1a span
  • 机器学习方法简介(2)--决策树、随机森林、朴素贝叶斯

    1 决策树 决策树是一种用于对实例进行分类的树形结构 Hunt算法 是一种采用局部最优策略的决策树构建算法 xff0c 它同时也是许多决策树算法的基础 xff0c 包括ID3 C4 5和CART等 Hunt算法的递归定义如下 xff1a 1
  • 软件工程——结构化分析方法

    结构化方法 概念 用来指导软件项目的开发 一种系统化的软件开发方法包括 xff1a 结构化分析方法 结构化设计方法 结构化程序设计方法 结构化设计方法和结构化程序设计方法的区别 xff0c 前者指的软件开发设计阶段的软件体系架构以及内部模块
  • linux安装软件方式--源码编译安装

    简介 xff1a 介绍源码编译安装软件包的管理 1 源码安装优点 xff1a 编译安装过程 xff0c 可以设定参数 xff0c 指定安装目录 xff0c 按照需求进行安装 xff0c 指定安装的版本 xff0c 灵活性比较大 2 源码安装
  • 正点原子mpu6050数据读取失败问题

    如果下载他们官方的程序都读不出来的话 看看你买的是stm32f407的V3版本吗 xff1f 这个版本是只有磁力计的官方代码 你用V3板跑他们的mpu的代码就会读不出来 xff0c 那个mpu6050的代码是已经停产的V2板子的
  • keil5 STM32F103 下载程序出错Flash Download failed - "Cortex-M3"

    1 背景 STM32F103单片机无法下载程序 最近在使用STM32单片机做项目 先是使用的H743单片机 xff0c 现在需要使用到F103单片机 H7烧写程序正常 xff0c 但是无法对F103烧写程序 错误为 xff1a Error
  • 略解总线带宽计算

    例1 xff1a 解 xff1a 时钟频率100MHz 也就是说一秒钟有100M个时钟周期 5个时钟周期传一个字 100M个时钟周期可以传100M 5 61 20M个字 也就是1秒钟可以传20M个字 一个字是16位 也就是2B 20M个字就
  • TX2(2): 安装JetPack L4T 3.1 (9003载板)

    参考官网教程 xff0c 其实官网教程已经挺详细 xff0c 主要看官网教程就行 http docs nvidia com jetpack l4t 3 1 index html developertools mobile jetpack l
  • String字符串编码格式转换(UTF8/GBK)

    1 转UTF8编码 string StdStringToUTF8 const string amp str int nwLen 61 MultiByteToWideChar CP ACP 0 str c str 1 NULL 0 wchar
  • 前缀树(Trie树)

    前缀树是一种用于快速检索的多叉树结构 xff0c 利用字符串的公共前缀来降低查询时间 xff0c 核心思想是空间换时间 xff0c 经常被搜索引擎用于文本词频统计 优点 xff1a 最大限度地减少无谓的字符串比较 xff0c 查询效率高 x
  • C++串口通信

    一 串口通信的基本原理 串口的本质功能是作为 CPU 和串行设备间的编码转换器 当数据从 CPU 经过串行端口发送出去时 xff0c 字节数据转换为串行的位 xff08 bit xff09 xff1b 在接收数据时 xff0c 串行的位被转
  • 死锁的四个必要条件以及处理策略

    一 什么是死锁 死锁是指两个或两个以上的进程 xff08 线程 xff09 在运行过程中因争夺资源而造成的一种僵局 例如 xff0c 某计算机系统中只有一台打印机和一台输入设备 xff0c 进程P1正占用输入设备 xff0c 同时又提出使用
  • EM算法简介

    1 简介 EM算法是一种迭代优化策略 xff0c 由于它的计算方法中每一次迭代都分两步 xff0c 其中一个为期望步 xff08 E步 xff09 xff0c 另一个为极大步 xff08 M步 xff09 xff0c 所以算法被称为EM算法
  • 三菱PLC MC协议

    1 MC协议的目的 xff1a 允许外部设备读写PLC内部寄存器 2 协议格式 xff1a 通讯方式有RS485和TCP IP两种 xff0c 通讯格式有很多种 xff1a 3E 3C 4C 4E帧格式 xff0c 通讯内容分为二进制和AS
  • find和find_if用法

    一 find的用法 STL容器中有很多find xff0c 比如说set xff0c map 他们内部都有内置的find函数 xff0c 一般情况下 xff0c 如果我们用到这些容器 xff0c 那么我们直接用它的内置find就可以了 xf
  • QTreeView节点拖放

    拖放操作分为拖动 Drag 和放置 Drop 两种操作 xff0c 当拖动时需要把拖动的数据进行存储 称为编码 xff0c 数据存储为QMimeData类型的对象 称为放置数据 xff0c 当执行放置操作时需要把存储的数据读取出来 称为解码