使用PyQt 5我一直试图找到一种方法,通过使用QStandardItemModel和QStandarItems在QTreeView情境中对项目进行拖放操作来获取旧父级。
如果可能的话,我真的想避免创建自己的模型。
我当前的尝试是将当前父项存储在项目中,当它被创建为“旧父项”时,它不应该在移动中更新,因此我可以引用它更新旧父项中的值然后更新移动项目中的“旧父项”到新的当前父项。
我似乎无法让它工作,这是我在创建项目时尝试用来存储“旧父”的代码:
item.setData(parent.index(),(Qt.UserRole+3))
当我运行此操作时,我收到以下错误:
QVariant :: save:无法保存类型'QModelIndex'(类型ID:42)。
此时我无法引用旧的父母......
我找到了一个使用c ++和大量“指针转换”的引用,但我无法弄清楚如何将代码转换为Python和PyQt 5.
C ++参考:https://forum.qt.io/topic/1690/qvariant-save-load-unable-to-save-type-x/19
感谢您的帮助!
答案 0 :(得分:1)
模型的some signals会在插入或移除项目的子项时触发,因此这些项目可用于自动更新项目。
经过一些实验,我发现信号需要与queued connection一起使用,以便模型有机会完全更新:
model.rowsInserted.connect(slot, type=QtCore.Qt.QueuedConnection)
model.rowsRemoved.connect(slot, type=QtCore.Qt.QueuedConnection)
但除此之外,实施非常简单。无需在项目中存储任何额外信息,因为可以动态执行更新。
这是一个基本的演示脚本:
from PyQt5 import QtCore, QtGui, QtWidgets
class Window(QtWidgets.QTreeView):
def __init__(self):
super(Window, self).__init__()
self.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
self.setDragDropOverwriteMode(False)
self.header().hide()
model = QtGui.QStandardItemModel(self)
model.rowsInserted.connect(
self.sumItems, type=QtCore.Qt.QueuedConnection)
model.rowsRemoved.connect(
self.sumItems, type=QtCore.Qt.QueuedConnection)
self.setModel(model)
parent = model.invisibleRootItem()
for index in range(3):
item = QtGui.QStandardItem('0')
parent.appendRow(item)
for row in range(1, 5):
child = QtGui.QStandardItem(str(row))
item.appendRow(child)
self.expandAll()
def sumItems(self, index, first, last):
if index.isValid():
total = 0
parent = self.model().itemFromIndex(index)
for row in range(parent.rowCount()):
child = parent.child(row)
if child is not None:
total += int(child.text())
parent.setText(str(total))
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(700, 100, 250, 300)
window.show()
sys.exit(app.exec_())