2017-01-07 109 views
1

使用PyQt 5我一直在試圖找到一種方式來使用QStandardItemModel和QStandarItems從QTreeView情況下的項中拖放操作獲取舊父項。PyQt 5 QStandardItem存儲舊父

我真的想避免創建我自己的模型,如果可能的話。

我當前的嘗試是將當前父項作爲「舊父項」創建時存儲,並且它不應該在移動中更新,以便我可以引用它來更新舊父項中的值,然後將移動項目中的「舊父項目」更新爲新的當前父項目。

我似乎無法得到它的工作,雖然,這裏是我試圖用它來存儲「老家長」項目時創建的代碼:

item.setData(parent.index(),(Qt.UserRole+3)) 

當我運行這個,但是我出現以下錯誤:

QVariant::save: unable to save type 'QModelIndex' (type id: 42).

,我不能在這一點上引用舊的父...

我發現一個參考使用C++和大量的「指針鑄造」,但我想不出如何將代碼轉換爲Python和PyQt的5

C++參考:https://forum.qt.io/topic/1690/qvariant-save-load-unable-to-save-type-x/19

感謝您的幫助!

+0

以您目前的嘗試,只要你拖放一個項目,它的所有兒童的存儲索引(以及他們的孩子,等等)會立即無效。所以這種方法不管用,不管它是如何實現的。通過這樣做你試圖解決的實際問題是什麼? – ekhumoro

+0

我試圖更新一列的總和,當我從它刪除一行項目,並將其放在樹中的另一個位置。每個父節點都有一個總和項目,用於保存列中子項目的總和,我試圖在每次移動項目時都更新總項目。我希望這是有道理的! – Zexelon

回答

0

該模型有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_()) 
+0

這正是我一直在尋找的!我完全無法理解文檔WRT rowsInserted和rowsRemoved。例如,模型中的rowCount不會通過向項目添加子項(使用item.appendRow())更改,但這些信號仍然被髮送... – Zexelon