Qt 如何检测QStandardItemModel中的一个项目被放到另一个项目上?
我如何接收到一个通知,即a被拖放到另一个QStandardItem上,从而成为后者的子项 我原以为可以通过重新实现来实现这一点,但在删除后不会调用它:(下面是我尝试执行的一个示例。要进行测试,请运行程序并将树视图中的一项删除到另一项上。如果成功,您应该在控制台中看到已调用Qt 如何检测QStandardItemModel中的一个项目被放到另一个项目上?,qt,python-3.x,drag-and-drop,pyqt,pyqt5,Qt,Python 3.x,Drag And Drop,Pyqt,Pyqt5,我如何接收到一个通知,即a被拖放到另一个QStandardItem上,从而成为后者的子项 我原以为可以通过重新实现来实现这一点,但在删除后不会调用它:(下面是我尝试执行的一个示例。要进行测试,请运行程序并将树视图中的一项删除到另一项上。如果成功,您应该在控制台中看到已调用moveRows的确认 from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * class Model(QStan
moveRows
的确认
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Model(QStandardItemModel):
def moveRows(
self, source_parent, source_row, count, destination_parent,
destination_child):
print(
'Moving {} row(s) from row {} of parent {} to row {} of parent {}'
.format(
count, source_row, source_parent, destination_child,
destination_parent)
)
super().moveRows(
source_parent, source_row, count, destination_parent,
destination_child)
return True
def _create_item(text):
item = QStandardItem(text)
flags = Qt.ItemIsDragEnabled | Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsDropEnabled
item.setFlags(flags)
return item
model = Model()
model.appendRow([_create_item('Item 1')])
model.appendRow([_create_item('Item 2')])
app = QApplication([])
view = QTreeView()
view.setDragDropMode(view.InternalMove)
view.setModel(model)
view.show()
app.exec_()
通过研究QStandardItemModel源代码,我意识到必须重写,以便对条目丢失做出反应。QStandardItemModel在其
dropMimeData
的实现中移动条目,但子类无法以某种方式连接,因此您必须自己处理dropMimeData
这是基于mydropMimeData
的解决方案,MIME数据中包含的项目表示形式为Python pickle:
import pickle
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
_mimeType = 'application/x-standarditemmodeldatalist'
class Model(QStandardItemModel):
def dropMimeData(
self, data, action, row, column, parent):
# Access parent before calling super implementation, because it may mutate parent
dest_str = 'parent {}'.format(parent.data(Qt.DisplayRole)) if \
parent.isValid() else 'root'
ret_val = super().dropMimeData(data, action, row, column, parent)
if action != Qt.MoveAction or not data.hasFormat(_mimeType):
return ret_val
item_data = pickle.loads(data.data(_mimeType))[0]
print('Moving {} to {}'.format(item_data, dest_str))
return True
# Override in order to add custom MIME data
def mimeData(self, indexes):
mimeData = super().mimeData(indexes)
data = [index.data(Qt.DisplayRole) for index in indexes]
mimeData.setData(_mimeType, pickle.dumps(data))
return mimeData
# Override in order to announce our custom MIME type
def mimeTypes(self):
return super().mimeTypes() + [_mimeType]
def _create_item(text):
item = QStandardItem(text)
flags = Qt.ItemIsDragEnabled | Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsDropEnabled
item.setFlags(flags)
return item
model = Model()
model.appendRow([_create_item('Item 1')])
model.appendRow([_create_item('Item 2')])
app = QApplication([])
view = QTreeView()
view.setDragDropMode(view.InternalMove)
view.setModel(model)
view.show()
app.exec_()