PyQt 的Tree Widget中拖放和点击的异常行为

在 PyQt 的 QTreeWidget 中,如果你遇到 拖放点击 的异常行为,可能是由于信号处理、事件拦截、拖放设置或树结构配置等问题导致的。以下是一些可能的常见问题和解决方案。

在这里插入图片描述

1、问题背景

一个 PyQt 应用程序中包含两个 Tree Widget,当用户从一个 Tree Widget 拖动项目并将其释放到另一个 Tree Widget 时,程序运行良好。但是,如果用户将项目拖动并释放到相同的 Tree Widget(这是一种不希望的行为,因此我在代码中禁用了接受拖放操作),Tree Widget 会忽略用户接下来的鼠标点击事件。

当用户拖动一个项目并将其释放到相同的 Tree Widget 时,可以看到以下问题:

  1. 用户点击左侧 Tree Widget 中的任何项目,而不会发生任何变化。
  2. 用户再次点击相同或其他项目时,选择才会发生改变。
  3. 试图点击展开图标,无论用户点击多少次,都不会触发任何事件。

要重现此问题,请运行代码并执行以下步骤:

  1. 从左侧的树中拖动一个项目,并将其释放到相同的树中。
  2. 单击左侧树中的任何项目,您将注意到没有任何变化
  3. 再次单击相同或其他项目,选择就会更改。

2、解决方案

为了解决这个问题,我修改了 MyTreeWidgetmousePressEvent 方法,以确保在用户点击 Tree Widget 时鼠标按下位置被正确记录。之前,mousePressEvent 方法只在左键点击时记录鼠标按下位置,这导致了上述异常行为。现在,只要用户点击 Tree Widge,即使没有按下左键,鼠标按下位置都会被记录。

修改后的 mousePressEvent 方法如下:

class MyTreeWidget(QtGui.QTreeWidget):# ...def mousePressEvent(self, event):super(MyTreeWidget, self).mousePressEvent(event)self.mousePressPos = event.pos()

这样可以确保鼠标按下位置始终被正确记录,从而解决了上述异常行为。

完整的代码如下:

from PyQt4 import QtGui, QtCore
import cPickleclass MyTreeItem(QtGui.QTreeWidgetItem):def __init__(self, parent=None):super(MyTreeItem, self).__init__(parent)self.setFlags(QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsDropEnabled)def getPath(self):"""Rebuild path from the tree."""if isinstance(self.parent(), MyTreeItem):path = '{0}/{1}'.format(self.parent().getPath() ,str(self.text(0)))#The top level itemelse:path = '/{0}'.format(str(self.text(0)))return pathdef getParents(self):"""Get all the parents to the top level."""parents = []while self:self = self.parent()if isinstance(self, MyTreeItem):parents.append(self)return parentsdef getChildren(self):"""Get all the children(flatten)."""children = []if not self:return childrenchildrenCount = self.childCount()if childrenCount == 0:return childrenfor idx in range(childrenCount):citem = self.child(idx)if citem:children.append(citem)children.extend(citem.getChildren())return childrenclass MyTreeWidget(QtGui.QTreeWidget):def __init__(self, parent = None):super(MyTreeWidget, self).__init__(parent)self.setDragEnabled(True)self.setAcceptDrops(True)self.setHeaderLabels(["Select Members"])self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)self.mousePressPos = QtCore.QPoint(0,0)def mousePressEvent(self, event):super(MyTreeWidget, self).mousePressEvent(event)self.mousePressPos = event.pos()def mouseMoveEvent(self, event):super(MyTreeWidget, self).mouseMoveEvent(event)self.setAcceptDrops(False)drag = QtGui.QDrag(self)mime_data = QtCore.QMimeData()passme = []for sel in self.selectedItems():dnddict = {}dnddict['disp'] = sel.getPath()dnddict['val'] = sel.getPath()passme.append(dnddict)bstream = cPickle.dumps(passme)mime_data.setData("application/x-ltreedata", bstream)drag.setMimeData(mime_data)self.setAcceptDrops(True)action = drag.exec_()def mouseReleaseEven(self, event):self.setAcceptDrop(True)event.accept()def dragMoveEvent(self, event):if event.mimeData().hasFormat("application/x-ltreedata"):event.accept()else:event.ignore()def dragEnterEvent(self, event):if event.mimeData().hasFormat("application/x-ltreedata"):event.accept()else:event.ignore()def dropEvent(self, event):if event.source() == self:event.ignore()else:for item in event.source().selectedItems():print item.text(0)def addItems(self, itemList):"""Take a list of path-like strings"""for item in itemList:self.addItem(item)def addItem(self, item):"""Convert each item to a tree item"""joints = item.strip('/').split('/')joint = Nonewhile joints:joint = self.addTreeJoint(joints.pop(0), joint)def addTreeJoint(self, jointName, parent=None):"""Add item to the tree widget"""returnItem = None#If it the top of the treeif not parent:#Find existing itemfor item in self.findItems(QtCore.QString(jointName),QtCore.Qt.MatchExactly):if jointName == item.text(0):return item#Create new top level itemreturnItem = MyTreeItem(self)returnItem.setText(0, jointName)#We search all the children of this tree level and figure out if#we need to create a new tree item.else:for idx in range(parent.childCount()):if parent.childCount() == 0:breakif jointName == parent.child(idx).text(0):return parent.child(idx)#Create new itemreturnItem = MyTreeItem(parent)returnItem.setText(0, jointName)return returnItemclass GeometrySelector(QtGui.QWidget):accepted = QtCore.pyqtSignal(list)def __init__(self, parent = None):super(GeometrySelector, self).__init__(parent)self.treeWidget = MyTreeWidget(self)self.treeWidget.addItems(get_objs())button = QtGui.QPushButton('Add Members', self)button.setFocusPolicy(QtCore.Qt.NoFocus)button.clicked.connect(self.cb_accept)filterLabel = QtGui.QLabel(self)filterLabel.setText('Filter:')filterField = QtGui.QLineEdit(self)filterField.textChanged.connect(self.filterChanged)filterBox = QtGui.QHBoxLayout()filterBox.addWidget(filterLabel)filterBox.addWidget(filterField)mainLayout = QtGui.QGridLayout()mainLayout.addWidget(self.treeWidget,0,0)mainLayout.addLayout(filterBox,1,0)mainLayout.addWidget(button,2,0)self.setLayout(mainLayout)pal = self.palette()pal.setColor(QtGui.QPalette.Base, QtGui.QColor(80, 80, 80))pal.setColor(QtGui.QPalette.Text, QtGui.QColor(230, 230, 230))self.setPalette(pal)button.setPalette(pal)self.treeWidget.setPalette(pal)def filterChanged(self, filterStr):showedItem = []matchFlag = QtCore.Qt.MatchFlags(QtCore.Qt.MatchContains | QtCore.Qt.MatchRecursive | QtCore.Qt.MatchRegExp)allItems = self.treeWidget.findItems(QtCore.

过这些调整,通常可以解决 PyQt QTreeWidget 中的拖放和点击行为异常问题。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

QUUID 使用详解

UUID 通常由 128 位(16 字节)组成,通常表示为 32 个十六进制数字,分为五个部分,格式如下: QUuid 是 Qt 框架中用于生成和处理 UUID(通用唯一标识符)的类。UUID 是一种标准的标识符格…

(27)QPSK信号在非相关平坦莱斯(Rician)衰落信道上的误码率性能MATLAB仿真

文章目录 前言一、Rician衰落信道模型的MATLAB代码二、在非相关的平坦Rician衰落信道上传输QPSK符号模型1.MATLAB仿真代码2.仿真结果 前言 本文首先给出莱斯衰落信道的建模函数,然后基于该函数给出在非相关的平坦Rician衰落信道上传输QPSK数字调制符号的MATLAB仿真…

6. 继承、重写、super、final

文章目录 一、重新定义需求二、继承1. 继续分析2. 概念3. 代码① 父类② 子类③ 测试结果 4. 饿狼传说之多层继承① 概念② 代码 5. 多继承 三、方法的重写1. 情境2. 代码① 吃什么② 怎么叫(Override重写) 3. 小结 四、super1. 啃老2. 啃老啃到底 五、final1. 用途及特征2. 举…

快速解决urllib3.exceptions.MaxRetryError: HTTPSConnectionPool

正题 使用pip命令查看urllib3版本 pip list发现版本为 1.26.9 urllib3 v1.26.9此时如下报错,无法正常使用(使用了代理) urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(hostxxx.xxxxx.com, port443): Max retries exceeded wit…

智能的三大问题:何以、所以、可以

智能具有三大问题,即何以、所以、可以。“何以(Why)”涉及探讨智能的本质及其产生的原因。智能是什么?它的定义和特征是什么?为什么人类或机器需要智能?它如何帮助我们解决复杂问题、做出决策和适应环境&am…

(五)Proteus仿真STM32单片机串口数据流收发

(五)Protues仿真STM32单片机串口数据流收发 – ARMFUN 1,打开STM32CubeMX,找到USART1,配置模式Asynchronous,此时PA9、PA10自动变成串口模式 串口默认参数:115200bps 8bit None 1stop 2,NVIC Settings使能…

【Ubuntu】在Ubuntu上安装IDEA

【Ubuntu】在Ubuntu上安装IDEA 零、前言 最近换了Ubuntu系统,但是还得是要写代码,这样就不可避免地用到IDEA,接下来介绍一下如何在Ubuntu上安装IDEA。 壹、下载 这一步应该很容易的,直接打开IDEA的下载页面,点击下…

科研绘图系列:R语言绘制SCI文章图2

文章目录 介绍加载R包导入数据图a图b图d系统信息介绍 文章提供了绘制图a,图b和图d的数据和代码 加载R包 library(ggplot2) library(dplyr) library(readxl) library(ggpmisc)导入数据 数据可从以下链接下载(画图所需要的所有数据): 百度网盘下载链接: https://pan.baid…

2024年软件设计师中级(软考中级)详细笔记【3】数据结构(下)(分值5分)

上午题第3章数据结构下部目录 前言第3章 数据结构【下】(5分)3.5 查找3.5.1 查找的基本概念【考点】3.5.2 静态查找表的查找方法3.5.3 动态查找表3.5.4 哈希表3.5.4.1 哈希表的定义3.5.4.2 哈希函数的构造方法3.5.4.3 处理冲突的方法 3.6 排序3.6.1 排序的基本概念3.6.2 简单排…

Java 获取热搜并生成图片

效果图如下&#xff1a; 第一步获取热搜 public List<String> getHotNews4(Integer size) {if (size < 0 || StringUtils.isEmpty(size)) {return null;}try {//set 转listreturn new ArrayList<>(getHotNews(size));} catch (Exception e) {logger.error(&qu…

Java 集合 Collection常考面试题

理解集合体系图 collection中 list 是有序的,set 是无序的 什么是迭代器 主要遍历 Collection 集合中的元素,所有实现了 Collection 的集合类都有一个iterator()方法,可以返回一个 iterator 的迭代器。 ArrayList 和 Vector 的区别? ArrayList 可以存放 null,底层是由数…

Java控制台实现《多线程模拟龟兔赛跑》(实现Runnale接口,重写run()方法)

&#xff08;温馨提示&#xff1a;本题最重要的是学习思路&#xff0c;代码还有待优化和改进&#xff01;&#xff09; 下一篇博客进行优化。实现Callable接口&#xff1a;V call() throws Exception 。可以返回结果&#xff0c;以及可以抛出异常。&#xff08;启动线程比较麻烦…

JavaSE——集合2:List(Iterator迭代器、增强for、普通for循环遍历集合)

目录 一、List (一)List接口基本介绍 二、List接口的常用方法 三、List集合的三种遍历方式 四、小练习——使用冒泡排序遍历集合 一、List (一)List接口基本介绍 List接口是Collection接口的子接口 public interface List<E> extends Collection<E> List集…

Matlab实现海洋捕食者优化算法优化回声状态网络模型 (MPA-ESN)(附源码)

目录 1.内容介绍 2部分代码 3.实验结果 4.内容获取 1内容介绍 海洋捕食者优化算法&#xff08;Marine Predators Algorithm, MPA&#xff09;是一种基于海洋生物捕食行为的新型群体智能优化算法。MPA通过模拟海洋捕食者如鲨鱼、海豚等在寻找猎物时的追踪、包围和攻击行为&…

高质量SCI论文撰写及投稿丨论文选题、文献调研、实验设计、数据分析、论文结构及语言规范等----AI强大功能

科学研究的核心在于将复杂的思想和实验成果通过严谨的写作有效地传递给学术界和工业界。对于研究生、青年学者及科研人员&#xff0c;如何高效撰写和发表SCI论文&#xff0c;成为提升学术水平和科研成果的重要环节。系统掌握从选题到投稿的全过程&#xff0c;提高论文撰写效率与…

区块链积分系统:重塑支付安全与商业创新的未来

在当今社会&#xff0c;数字化浪潮席卷全球&#xff0c;支付安全与风险管理议题日益凸显。随着交易频次与规模的不断扩大&#xff0c;传统支付体系正面临前所未有的效率、合规性和安全挑战。 区块链技术&#xff0c;凭借其去中心化、高透明度以及数据不可篡改的特性&#xff0c…

React(一) 认识React、熟悉类组件、JSX书写规范、嵌入变量表达式、绑定属性

文章目录 一、初始React1. React的基本认识2. Hello案例2.1 三个依赖2.2 渲染页面2.3 hello案例完整代码 二、类组件1. 封装类组件2. 组件里的数据3. 组件里的函数 (重点)4. 案例练习(1) 展示电影列表 三、JSX语法1. 认识JSX2. JSX书写规范及注释3. JSX嵌入变量作为子元素4. JS…

Linux操作系统小项目——实现《进程池》

文章目录 前言&#xff1a;代码实现&#xff1a;原理讲解&#xff1a;细节处理&#xff1a; 前言&#xff1a; 在前面的学习中&#xff0c;我们简单的了解了下进程之间的通信方式&#xff0c;目前我们只能知道父子进程的通信是通过匿名管道的方式进行通信的&#xff0c;这是因…

【gRPC】4—gRPC与Netty

gRPC与Netty ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; &#x1f4d6;RPC专栏&#xff1a;https://…

力扣 前缀和

找子数组的个数了解前缀和的基础。 前缀和大致理解为到达某个位置&#xff0c;前面几个数的总和&#xff0c;即s[i1]s[i]a[i1]&#xff0c;可以通过一次循环获得。然后几个前缀和作差&#xff0c;即可得到某个位置到某个位置的和&#xff0c;根据map的键值对进行更新次数。 题…