2017-01-07 11 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++ 및 "포인터 캐스팅"를 많이 사용하여 하나의 참조를 찾았지만 나는 이해할 수 없었다 밖으로 어떻게 파이썬과 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은 항목의 하위 항목이 삽입되거나 제거 될 때마다 실행되므로 항목을 자동으로 업데이트하는 데 사용할 수 있습니다.

model.rowsInserted.connect(slot, type=QtCore.Qt.QueuedConnection) 
model.rowsRemoved.connect(slot, type=QtCore.Qt.QueuedConnection) 

하지만 그 이외는, 구현이 매우 간단합니다 :

몇 가지 실험 후, 나는 모델이 완벽하게 업데이트 할 수있는 기회를 가질 수 있도록 신호가하는 queued connection로 사용할 필요가 있음을 발견했다. 업데이트가 동적으로 수행 될 수 있으므로 항목에 추가 정보를 저장할 필요가 없습니다. 여기

기본적인 데모 스크립트입니다 : 바로 드래그 앤 항목을 드롭으로, 현재의 시도와

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