Python QTreeWidget仅在按键时拖放 >让我们来考虑一下这个小片段: import sys import random import string from PyQt5 import QtWidgets from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QMenu, QAction, \ QTreeWidget, QTreeWidgetItem, QAbstractItemView from PyQt5.QtGui import QCursor, QKeySequence class PageTree(QTreeWidget): def __init__(self, parent=None): super().__init__(parent) self.alphabet = list(string.ascii_lowercase) self.index = 0 self.header().hide() self.view_menu = QMenu(self) self.create_actions() self.setDragEnabled(True) self.setDragDropMode(QAbstractItemView.InternalMove) self.setSelectionBehavior(QAbstractItemView.SelectRows) def create_actions(self): action = QtWidgets.QAction("Add new", self.view_menu) action.triggered.connect(self.on_add_page) action.setShortcuts(QKeySequence("a")) self.view_menu.addAction(action) self.addActions(self.view_menu.actions()) def add_page(self, name, parent=None): if (parent is None and len(self.selectedItems()) == 1): parent = self.selectedItems()[0] item = QTreeWidgetItem(parent) item.setText(0, name) item.setFlags(item.flags() | Qt.ItemIsEditable) self.addTopLevelItem(item) if (parent): parent.setExpanded(True) return item def on_add_page(self): self.add_page("test_page_{0}".format(self.alphabet[self.index]), None) self.index += 1 self.index %= len(self.alphabet) def contextMenuEvent(self, ce): super().contextMenuEvent(ce) self.view_menu.exec(QCursor.pos()) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) tree_widget = PageTree() tree_widget.resize(400, 600) tree_widget.show() sys.exit(app.exec_())

Python QTreeWidget仅在按键时拖放 >让我们来考虑一下这个小片段: import sys import random import string from PyQt5 import QtWidgets from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QMenu, QAction, \ QTreeWidget, QTreeWidgetItem, QAbstractItemView from PyQt5.QtGui import QCursor, QKeySequence class PageTree(QTreeWidget): def __init__(self, parent=None): super().__init__(parent) self.alphabet = list(string.ascii_lowercase) self.index = 0 self.header().hide() self.view_menu = QMenu(self) self.create_actions() self.setDragEnabled(True) self.setDragDropMode(QAbstractItemView.InternalMove) self.setSelectionBehavior(QAbstractItemView.SelectRows) def create_actions(self): action = QtWidgets.QAction("Add new", self.view_menu) action.triggered.connect(self.on_add_page) action.setShortcuts(QKeySequence("a")) self.view_menu.addAction(action) self.addActions(self.view_menu.actions()) def add_page(self, name, parent=None): if (parent is None and len(self.selectedItems()) == 1): parent = self.selectedItems()[0] item = QTreeWidgetItem(parent) item.setText(0, name) item.setFlags(item.flags() | Qt.ItemIsEditable) self.addTopLevelItem(item) if (parent): parent.setExpanded(True) return item def on_add_page(self): self.add_page("test_page_{0}".format(self.alphabet[self.index]), None) self.index += 1 self.index %= len(self.alphabet) def contextMenuEvent(self, ce): super().contextMenuEvent(ce) self.view_menu.exec(QCursor.pos()) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) tree_widget = PageTree() tree_widget.resize(400, 600) tree_widget.show() sys.exit(app.exec_()),python,python-3.x,drag-and-drop,pyqt,pyqt5,Python,Python 3.x,Drag And Drop,Pyqt,Pyqt5,如您所见,当前代码显示了一个简单的QTreeWidget,它允许您使用内置的拖放功能重新排序项目,这要归功于setDragEnabled、setDragDropMode、setSelectionBehavior函数 事情是这样的,我想实现一种行为,只有在按下一个键(即:ctrl)时才会发生拖放。否则,我希望小部件能够正常运行,并且无论您是尝试拖动项目还是在悬停项目时按住鼠标按钮,项目都保持静态 如何实现此行为?通过覆盖startDrag,这非常容易实现: class PageTree(QTree

如您所见,当前代码显示了一个简单的QTreeWidget,它允许您使用内置的拖放功能重新排序项目,这要归功于
setDragEnabled、setDragDropMode、setSelectionBehavior
函数

事情是这样的,我想实现一种行为,只有在按下一个键(即:ctrl)时才会发生拖放。否则,我希望小部件能够正常运行,并且无论您是尝试拖动项目还是在悬停项目时按住鼠标按钮,项目都保持静态


如何实现此行为?

通过覆盖
startDrag
,这非常容易实现:

class PageTree(QTreeWidget):
    ...

    def startDrag(self, actions):
        if QtWidgets.qApp.keyboardModifiers() & Qt.MetaModifier:
            super().startDrag(actions)

请注意,我在这里使用了Meta(Windows)键,因为它与鼠标一起影响选择的各个方面。(另外,在Linux上,Alt+drag组合通常用于移动窗口,因此它也可能不是一个好的选择)。但是,您可以通过选择不同的解决方案来解决此问题。

哇,这确实很容易:)。尽管如此,我还是不明白使用控制键有什么问题,我已经试过了,而且效果很好。。。我错过什么了吗?@BPL。对我来说,使用控制键可能与选择冲突。如果未选择某个项目,则按住ctrl键并拖动即可。但如果选中该项,则初始ctrl+单击将取消选中该项,并且拖动失败。我想这一定是特定于平台的问题。很久以前我问这个问题时,我不知道你所说的控制键冲突选择是什么意思,也没有坚持(我认为它工作正常),但今天我尝试使用一些旧的小部件,我终于成功了。我试图找到一个合适的解决方案,但仍然能够使用控制修改器(窗口元键将弹出windows开始菜单),但还没有找到任何东西。到目前为止有什么建议吗?@BPL。你不能两全其美,所以你要么关闭扩展选择,要么选择一个不冲突的鼠标+按键组合。