我试图让拖动&使用自定义的QStandardItem在两个QListView之间工作。 我找不到除this document之外的其他信息,这些信息有一点帮助,但现在我卡住了。如何将自定义的QStandardItem放入QListView中
拖动从一个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 - i.e. 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_())
的想法是被丢弃的数据进行解码,以获得原始的项背,然后进行复制和追加该副本到接收模型。 自定义项目被追加到模型中,但它在放置事件后不会显示在视图中。如果我在拖放内创建一个新的自定义项目并追加它,那么一切都按预期工作。
所以我就有关上述两个问题:
- 是这种做法是正确的,使的自定义项目的下落或有更简单的吗?
- 为什么上面的代码中的自定义项目的副本不会在放置后的视图中显示?
由于提前, 坦率
我问[这个问题](http://stackoverflow.com/questions/41991840/pyside-qlistview-creating-new-item - 时间 - 拖放 - 而不是传递 - 或)稍早一点。我试图按照您的解决方案,但是我仍然无法在移动事件中维护自定义数据。我不知道如何正确实现'setData'方法。你能否扩展一下如何正确实现'setData'?我不确定这次讨论的最佳格式是什么(新问题?),但这里是[我的代码与更改](https://www.pastiebin.com/5892bb18723f8)。 – Johndt6
@ Johndt6。我添加了一个我对我的答案意味着什么的例子。这个想法是完全避免动态python属性的所有用法。 “@ property”的使用只是语法糖。一个更简单的实现是使用纯粹的Qt APIs:即对于任何自定义值,使用'text()'/'setText()'','data()'/'setData()'''QStandardItem' 。应该不需要重新实现除clone()之外的其他任何东西。唯一相关的是项目标志和数据。 – ekhumoro