Как удалить пользовательский QStandardItem в QListView

Я пытаюсь получить drag & drop для работы между двумя QListViews, используя пользовательский QStandardItem. Я не могу найти информацию, в которой я нуждаюсь в Интернете, кроме этого документа, который немного помог, но теперь я застрял.

Перетаскивание из одного QListView в другое отлично работает, когда я использую QStandardItem для хранения моих данных, но когда я использую настраиваемый элемент, я сталкиваюсь с проблемой, потому что принимающая модель / представление создает QStandardItem, когда пользовательский элемент удаляется.

В идеале я мог бы сказать принимающей модели, чтобы использовать мой пользовательский элемент в качестве элемента по умолчанию, и в противном случае просто сделать это, но я полагаю, это будет не так просто ?! Кажется, что все работает из коробки, кроме создания QStandardItem после кавычки , а не моего пользовательского элемента, поэтому я надеюсь, что мне не нужно повторно изобретать колесо (перетаскивание), чтобы получить эту часть справа? !

Если мне придется заново изобрести колесо и реализовать dropEvent для представления, чтобы вручную добавить входящие элементы, я столкнулся с другой странностью. Вот мой тестовый код (включая некоторый код для декодирования отброшенных данных, которые я нашел в Интернете):

from PySide import QtCore, QtGui class MyItem(QtGui.QStandardItem): '''This is the item I'd like to drop into the view''' def __init__(self, parent=None): super(MyItem, self).__init__(parent) self.testAttr = 'test attribute value' class ReceivingView(QtGui.QListView): '''Custom view to show the problem - ie the dropEvent produces a QStandardItem rather than MyItem''' def __init__(self, parent=None): super(ReceivingView, self).__init__(parent) def decode_data(self, bytearray): '''Decode byte array to receive item back''' data = [] item = {} ds = QtCore.QDataStream(bytearray) while not ds.atEnd(): row = ds.readInt32() column = ds.readInt32() map_items = ds.readInt32() for i in range(map_items): key = ds.readInt32() value = MyItem() ds >> value #item[QtCore.Qt.ItemDataRole(key)] = value item = value data.append(item) return data def dropEvent(self, event): byteArray = event.mimeData().data('application/x-qabstractitemmodeldatalist') for item in self.decode_data(byteArray): copiedItem = MyItem(item) newItem = MyItem('hello') print copiedItem print newItem self.model().appendRow(copiedItem) # the copied item does not show up, even though it is appended to the model #self.model().appendRow(newItem) # this works as expected event.accept() item = self.model().item(self.model().rowCount() - 1) print item if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) mw = QtGui.QMainWindow() w = QtGui.QSplitter() mw.setCentralWidget(w) # models model1 = QtGui.QStandardItemModel() model2 = QtGui.QStandardItemModel() for i in xrange(5): #item = QtGui.QStandardItem() item = MyItem() item.setData(str(i), QtCore.Qt.DisplayRole) model1.appendRow(item) # views view1 = QtGui.QListView() view2 = ReceivingView() for v in (view1, view2): v.setViewMode(QtGui.QListView.IconMode) view1.setModel(model1) view2.setModel(model2) w.addWidget(view1) w.addWidget(view2) mw.show() mw.raise_() sys.exit(app.exec_()) 

Идея состоит в том, чтобы декодировать упавшие данные для получения исходного элемента назад, затем сделать копию и добавить эту копию в принимающую модель. Пользовательский элемент добавляется к модели, но он не отображается в представлении после события drop. Если я создаю новый пользовательский элемент внутри капли и добавлю его, все будет работать так, как ожидалось.

Поэтому у меня возникли два вопроса:

  1. Является ли этот подход правильным, чтобы включить отбрасывание пользовательских элементов или есть более простой?
  2. Почему копия пользовательского элемента в приведенном выше коде не отображается в представлении после капли?

Спасибо заранее, откровенный

One Solution collect form web for “Как удалить пользовательский QStandardItem в QListView”

Похоже, вы хотите setItemPrototype . Это обеспечивает фабрику элементов для модели, так что она будет неявно использовать ваш пользовательский класс, когда это необходимо.

Все, что вам нужно сделать, это reimplement clone() в вашем классе предметов:

 class MyItem(QtGui.QStandardItem): '''This is the item I'd like to drop into the view''' def __init__(self, parent=None): super(MyItem, self).__init__(parent) self.testAttr = 'test attribute value' def clone(self): return MyItem() 

Затем установите экземпляр этого класса в качестве прототипа в принимающей модели:

  # models model1 = QtGui.QStandardItemModel() model2 = QtGui.QStandardItemModel() model2.setItemPrototype(MyItem()) 

Вы можете забыть обо всех материалах с потоком данных.

PS:

Я полагаю, что я должен указать, что Qt, очевидно, ничего не знает о любых атрибутах данных python, которые могли быть установлены во время жизни элемента, и поэтому они не будут сериализованы, когда элемент передается во время операции перетаскивания. Если вы хотите сохранить такие данные, используйте setData() с настраиваемой ролью:

 class MyItem(QtGui.QStandardItem): _TestAttrRole = QtCore.Qt.UserRole + 2 def clone(self): item = MyItem() item.testArr = 'test attribute value' return item @property def testAttr(self): return self.data(self._TestAttrRole) @testAttr.setter def testAttr(self, value): self.setData(value, self._TestAttrRole) 
  • Есть ли какое-либо решение для утечки памяти QtWebKit?
  • Qt Creator как среда разработки Python?
  • Создайте меню PyQt из списка строк
  • Qt4: Напишите функцию, которая создает диалог и возвращает выбор пользователя
  • Виртуальный столбец в QTableView?
  • Qt / PyQt: Как создать виджет с раскрывающимся списком, например QLabel, QTextBrowser и т. Д.?
  • Qt Designer генерирует код на C ++
  • Pyside, основной вопрос webkit
  •  
    Interesting Posts for Van-Lav

    Pandas drop_duplicates – TypeError: тип аргумент объекта после * должен быть последовательностью, а не картой

    Леновые выборочные случайные результаты в python

    Python – cxfreeze продолжает говорить, что файл / каталог не существует

    Структура папок для Python Django-REST-framework и Angularjs

    Как построить линию (многоугольная цепь) с numpy / scipy / matplotlib с минимальным сглаживанием

    Извлечение неконтекстных слов на английском языке string – python

    Элегантный способ удаления смежных повторяющихся элементов в списке?

    Недопустимая форма Django

    Вложение вектора в массив, индексированный другим массивом

    Доступ к элементам в массиве Python

    Python – Заменить данные массива на 2 значения второго массива

    selenium move_to_element не всегда наводит указатель мыши

    Матричное умножение по элементам в NumPy

    изменять размер с усреднением или повторять массив numd 2d

    Как обращаться с добавлением элементов и их родителей с помощью xpath

    Python - лучший язык программирования в мире.