PyQt 5 QStandardItem存储旧父

时间:2017-01-07 06:16:11

标签: python drag-and-drop pyqt pyqt5 qstandarditemmodel

使用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

感谢您的帮助!

1 个答案:

答案 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_())