如何删除自定义QStandardItem成而QListView(How to drop a cust

2019-09-26 03:38发布

我试图让拖放到工作中使用自定义QStandardItem 2个QListViews之间。 我无法找到我需要的在线以外的信息这个文件这有助于一点点,但现在我卡住了。

拖放从一个而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_())

这个想法是被丢弃的数据进行解码,以获得原始的项背,然后进行复制和拷贝追加到接收模式。 自定义项追加到模型,但它并没有在drop事件后的视图中。 如果我甚至创造降内一个新的自定义项和追加,一切都按预期工作。

所以,我得到了有关上述两个问题:

  1. 这是做法是正确的,使的自定义项目的下落或有更简单的吗?
  2. 为什么自定义项目的在上面的代码拷贝不是在下降后的视图显示?

在此先感谢,坦诚

Answer 1:

它看起来像你想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()

一个然后设置类为原型在接收模型的一个实例:

    # 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)


文章来源: How to drop a custom QStandardItem into a QListView
标签: qt pyqt pyside