我試圖讓拖動&使用自定義的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