2017-01-07 34 views
1

Использование PyQt 5 Я пытаюсь найти способ заставить старый родитель из операции перетаскивания элемента в ситуации QTreeView использовать QStandardItemModel и QStandarItems.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++ Reference: 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