- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试向 QTreeWidget 拖放功能添加约束,以防止分支进入另一个根中的另一个分支。
下面是一个让事情更清楚的例子:
我有 4 个对象。让我们称它们为苹果、香蕉、胡萝卜、榴莲吧。
树看起来像这样:
isDelicious (Root)
|-- BackgroundObjects (Branch)
|-- Durian
|-- ForgroundObjects (Branch)
|-- Apple
|-- Banana
|-- Carrot
isSmelly (Root)
|-- BackgroundObjects (Branch)
|-- Apple
|-- Carrot
|-- ForgroundObjects (Branch)
|-- Banana
|-- Durian
因此,允许将对象从 BackgroundObjects 拖放到 ForgroundObjects,反之亦然,但不允许将它们拖放到不同根的分支上。
我已尝试重新实现 dragMoveEvent、dragEnterEvent 和 dropEvent 并对其进行子类化,如果我在 dragEnterEvent 中对事件调用 accept,它会在之后调用 dragMoveEvent(这是我所期望的)。但是,仅当我在 QTreeWidget 之外放置时才会调用 dropEvent。
我想做的是在移动之前检查所选对象的祖 parent ,以及建议的新祖 parent ,看看它们是否相同。如果是这样,则接受此举。否则忽略移动。
我已经搜索过是否有任何答案,但到目前为止我还没有看到任何我正在尝试做的事情。最接近的可能是 Stack Overflow 中的这两个问题:
https://stackoverflow.com/questions/17134289/managing-drag-and-drop-within-qtreewidgets-in-pyside
qt: QTreeView - limit drag and drop to only happen within a particlar grandparent (ancestor)
最佳答案
Qt 似乎并没有使这类事情变得很容易。
我能想到的最好办法是在拖动进入和拖动移动事件期间临时重置项目标志。下面的示例动态计算当前顶级项目以限制拖放。但也可以通过使用 setData()
为每个项目添加标识符来完成。
from PyQt4 import QtCore, QtGui
class TreeWidget(QtGui.QTreeWidget):
def __init__(self, parent=None):
QtGui.QTreeWidget.__init__(self, parent)
self.setDragDropMode(self.InternalMove)
self.setDragEnabled(True)
self.setDropIndicatorShown(True)
self._dragroot = self.itemRootIndex()
def itemRootIndex(self, item=None):
root = self.invisibleRootItem()
while item is not None:
item = item.parent()
if item is not None:
root = item
return QtCore.QPersistentModelIndex(
self.indexFromItem(root))
def startDrag(self, actions):
items = self.selectedItems()
self._dragroot = self.itemRootIndex(items and items[0])
QtGui.QTreeWidget.startDrag(self, actions)
def dragEnterEvent(self, event):
self._drag_event(event, True)
def dragMoveEvent(self, event):
self._drag_event(event, False)
def _drag_event(self, event, enter=True):
items = []
disable = False
item = self.itemAt(event.pos())
if item is not None:
disable = self._dragroot != self.itemRootIndex(item)
if not disable:
rect = self.visualItemRect(item)
if event.pos().x() < rect.x():
disable = True
if disable:
for item in item, item.parent():
if item is not None:
flags = item.flags()
item.setFlags(flags & ~QtCore.Qt.ItemIsDropEnabled)
items.append((item, flags))
if enter:
QtGui.QTreeWidget.dragEnterEvent(self, event)
else:
QtGui.QTreeWidget.dragMoveEvent(self, event)
for item, flags in items:
item.setFlags(flags)
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.tree = TreeWidget(self)
self.tree.header().hide()
def add(root, *labels):
item = QtGui.QTreeWidgetItem(self.tree, [root])
item.setFlags(item.flags() &
~(QtCore.Qt.ItemIsDragEnabled |
QtCore.Qt.ItemIsDropEnabled))
for index, title in enumerate(
('BackgroundObjects', 'ForegroundObjects')):
subitem = QtGui.QTreeWidgetItem(item, [title])
subitem.setFlags(
subitem.flags() & ~QtCore.Qt.ItemIsDragEnabled)
for text in labels[index].split():
child = QtGui.QTreeWidgetItem(subitem, [text])
child.setFlags(
child.flags() & ~QtCore.Qt.ItemIsDropEnabled)
add('isDelicious', 'Durian', 'Apple Banana Carrot')
add('isSmelly', 'Apple Carrot', 'Banana Durian')
root = self.tree.invisibleRootItem()
root.setFlags(root.flags() & ~QtCore.Qt.ItemIsDropEnabled)
self.tree.expandAll()
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.tree)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 300, 300)
window.show()
sys.exit(app.exec_())
关于python - pyside qtreewidget 约束拖放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20618044/
我想更新小部件的值,但为了防止无限循环,我需要防止调用此小部件的回调函数 .valueChanged信号。 以下示例完全按预期工作: Qt = PySide class MainWindow(Acto
使用以下代码,在尝试发出信号时出现错误(“PySide.QtCore.Signal”对象没有属性“emit”): #!/usr/bin/env python from PySide import Qt
我是 Python 新手。我同时安装了 Python 2.7 和 Python 3。我刚刚尝试通过 Homebrew 安装 PySide 并收到此消息: PySide package successf
是否可以使用 PySide 中的 Web 类之一加载包含按钮的本地 html/JS 文件,并将这些按钮连接到 PySide 插槽? 最佳答案 您可以使用 QtWebKit 将 QObject 导出到
我一直在寻找一个工作示例,该示例如何在使用 QT 设计器创建的 pyside 中嵌入 matplotlib 图,同时将逻辑保存在单独的文件中。我知道网上有很多例子,但没有一个真正使用 QT 设计器,然
我想我可以通过将\PySide 文件夹附加到我的环境的“搜索路径”来添加 PySide 库,但智能感知似乎没有发现任何东西。不过,它正在使用我的其他图书馆。有什么建议吗? 注意:我已经安装了 PTVS
我正在设计一个 Pyside Qt 应用程序,我想切换 QtCore.Qt.WindowStaysOnTopHint我的主窗口中的窗口标志。使用此代码设置此提示工作正常: self.setWindow
你如何在 PySide 中禁用声子? 我正在尝试使用 QWebpage 并且我不希望 phonon 启动,因为我正在编写的应用程序是服务器端应用程序,并且不需要媒体。我尝试了一些东西,但没有找到任何真
本文为大家分享了pyside pyqt实现鼠标右键菜单功能的具体代码,供大家参考,具体内容如下 在三维软件中使用pyside/pyqt编写gui界面时,为了艺术家使用操作的简洁,以及方便,经常会使
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我试图在 PySide 的单独线程中运行一个长任务,以便主线程可以继续处理 GUI 事件。我已经阅读了执行此操作的正确方法: 将任务封装在 QObject 子类中,其中工作在 run() 方法中完成,
我想知道如何根据最大标签的最大宽度/高度截断QLabel中的文本。 输入的文本可以是任意长度,但是为了保持整洁的布局,我想截断长字符串以填充最大空间(小部件的最大宽度/高度)。 例如。: 'A ve
我有一个界面,屏幕顶部有 4 个按钮,下面有 QFrame。我想根据按下的按钮更改 QFrame 中的布局。例如,如果按下 Button_1 显示一个 TextEdit Widget,如果按下 But
我想制作一个小部件的角。在 PyQt 中,我用样式表解决了这个问题,效果很好。我想在 PySide 中做同样的事情,但由于某些原因它不起作用。 这是我的代码: TitelWidget = QtGui.
我是 python 和 pyside 的新手。我将尝试成功运行以下代码。但现在我希望程序在显示窗口后等待用户无法使用它的定义时间,然后升级状态栏。我会尝试 sleep() 但不知道它必须以正确的方式放
我从 example of Zetcode 开始学习 PySide并尝试编写具有两个窗口的应用程序:“布局 View ”的父级“示意图 View ”,每个窗口都有菜单栏。启动时应该只是原理图窗口,布局
我从 example of Zetcode 开始学习 PySide并尝试编写具有两个窗口的应用程序:“布局 View ”的父级“示意图 View ”,每个窗口都有菜单栏。启动时应该只是原理图窗口,布局
我正在尝试通过 pyside 设置 QGridLayout 小部件的背景图像(位于与应用程序相同的文件夹中),但无济于事我已经查看了有关样式表的所有图、文档和论坛帖子,但仍然我不知道我做错了什么。 f
我有一个带有 5 个按钮的布局,我充当“菜单”,因此您单击一个按钮,会显示一个 View ,单击另一个按钮,会显示另一个 View 。我需要找出单击了哪个按钮,以便我可以根据按下的按钮执行某些操作。类
基本上我想要的是: 在主窗口中显示一个小部件,其中包含打开 QFileDialog 的按钮 选择文件后,包含按钮的小部件应切换到新的小部件,该新小部件会显示一些基于文件内容的可视化效果。 在下面的代码
我是一名优秀的程序员,十分优秀!