該模型有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_())
以您目前的嘗試,只要你拖放一個項目,它的所有兒童的存儲索引(以及他們的孩子,等等)會立即無效。所以這種方法不管用,不管它是如何實現的。通過這樣做你試圖解決的實際問題是什麼? – ekhumoro
我試圖更新一列的總和,當我從它刪除一行項目,並將其放在樹中的另一個位置。每個父節點都有一個總和項目,用於保存列中子項目的總和,我試圖在每次移動項目時都更新總項目。我希望這是有道理的! – Zexelon