gpt4 book ai didi

qt - 如何将自定义 QStandardItem 放入 QListView

转载 作者:行者123 更新时间:2023-12-04 13:33:25 27 4
gpt4 key购买 nike

我正在尝试使用自定义 QStandardItem 在两个 QListViews 之间进行拖放。
除了this document,我在网上找不到我需要的信息这有点帮助,但现在我被困住了。

从一个 QListView 拖放当我使用 QStandardItem 时,另一个工作正常保存我的数据,但是当我使用自定义项时遇到了麻烦,因为接收模型/ View 会创建 QStandardItem当自定义项目被丢弃时。

理想情况下,我可以告诉接收模型使用我的自定义项目作为默认项目,否则就这样做,但我想这不会那么容易?!
似乎除了创建 QStandardItem 之外,一切都是开箱即用的。掉落时,而不是我的自定义元素,所以我希望我不必为了得到那个部分而重新发明(拖放)轮子?!

如果我必须重新发明轮子并实现 View 的 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_())

这个想法是解码丢弃的数据以接收原始项目,然后制作一个副本并将该副本附加到接收模型。
自定义项被附加到模型中,但在放置事件之后它不会显示在 View 中。如果我在 drop even 中创建一个新的自定义项目并附加它,一切都会按预期工作。

所以我有两个关于上述问题的问题:
  • 这种方法是允许删除自定义项目的正确方法还是有更简单的方法?
  • 为什么上述代码中自定义项的副本在放置后没有显示在 View 中?

  • 提前致谢,
    坦率

    最佳答案

    看起来你想要 setItemPrototype .这为模型提供了一个项目工厂,因此它将在必要时隐式使用您的自定义类。

    您需要做的就是重新实现 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()

    然后将该类的一个实例设置为接收模型上的原型(prototype):
        # 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)

    关于qt - 如何将自定义 QStandardItem 放入 QListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39584001/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com