拖放操作分为拖动(Drag)和放下(Drop)两种操作,当数据拖动时会被存储为MIME(Multipurpose Internet Mail Extensions)类型。Qt中使用QMimeData类型来表示MIME数据,使用QDrag类来完成数据的转移,而整个拖动操作都是在几个鼠标的事件和拖放事件中完成的。
通常需要在视图本身中设置相关属性启动对拖放的内置支持:
- 设置dragEnabled属性为true,启用项拖动功能
- 设置 viewport() 的acceptDrops属性设置为true,允许用户在视图中放置内部或外部的项
- 设置视图的showDropIndicator属性,向用户显示当前正在拖动的项以及放置的位置。
- 设置视图的dragDropMode(QAbstractItemView::InternalMove),在视图中移动项目
import sys
from PySide2.QtWidgets import QTreeWidget, QTreeWidgetItem, QWidget, QVBoxLayout, QApplication
class TreeWidget(QTreeWidget):
def __init__(self):
super(TreeWidget, self).__init__()
self.setDragDropMode(QTreeWidget.InternalMove)
self.setDragEnabled(True) # 允许内部元素拖动
self.setColumnCount(1)
self.setHeaderLabels(['Key'])
root = QTreeWidgetItem(self)
root.setText(0, '根节点')
child1 = QTreeWidgetItem(root)
child1.setText(0, '子节点1')
child2 = QTreeWidgetItem(root)
child2.setText(0, '子节点2')
child3 = QTreeWidgetItem(child2)
child3.setText(0, '子节点2-1')
child4 = QTreeWidgetItem(child2)
child4.setText(0, '子节点2-2')
child5 = QTreeWidgetItem(child2)
child5.setText(0, '子节点2-3')
self.expandAll()
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.main_layout = QVBoxLayout()
tree = TreeWidget()
self.main_layout.addWidget(tree)
self.setLayout(self.main_layout)
self.resize(600, 800)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())