将 QDataStream 对象传递给另一个方法复制构造函数 vs 有状态

问题描述

在实现通用拖放模型时,我遇到了以下问题。编码mimeData时,我想将拖动索引的原始行和列写入数据流中。项目数据的序列化取决于程序员选择的特定数据结构,因此应以单独的方法封装。对其模型项使用不同数据结构的 DragDropListModel 的子类只需覆盖此封装方法即可。

问题在于 QDataStream 上的读/写是有状态的。 例如,请看一下 decode_data()。将 QDataStream 对象传递给负责解码流中下一项的方法,(可能)调用复制构造函数。现在 decode_item_from_stream() 使用数据流的副本。反序列化过程中完成的读取更改了复制的数据流对象的状态,但 decode_data() 中原始对象的状态保持不变。这应该会在 while 循环的下一次迭代中崩溃。

因此我的两个问题是:

  1. 我的描述准确还是我误解了什么?

  2. python 有没有办法规避这些问题(其他语言可能通过引用传递来解决这个问题),同时使方法彼此分开?

    class DragDropListModel(QtCore.QAbstractListModel):
        def __init__(self,tabText):
            super(DragDropListModel,self).__init__()
            self.model_data = []
    
        def data(self,index,role):
            item_data = self.model_data[index.row()]
    
            # DEBUG
            if role == QtCore.Qt.displayRole:
                return item_data[generic_tokens.display]
            if role == QtCore.Qt.decorationRole:
                return item_data[generic_tokens.decoration]
            if role == QtCore.Qt.ToolTipRole:
                item_data[generic_tokens.ToolTip]
            if role == generic_roles.ItemDaTarole:
                return item_data
    
        def rowCount(self,index):
            return len(self.model_data)
    
        def mimeTypes(self):
            """Returns the list of allowed MIME types"""
            return ["application/x-generic-drag-drop"]
    
        # Returns an object that contains serialized items of data corresponding to the list of indexes specified. 
        # The format used to describe the encoded data is obtained from the mimeTypes() function
        def mimeData(self,indexes:list):
            mimeData = QtCore.QMimeData()
            encodedData = self.encode_data(indexes)
            mimeData.setData("application/x-generic-drag-drop",encodedData)
            return mimeData
    
        def encode_data(self,indexes:list):
            byteArray = QtCore.QByteArray()
            dataStream = QtCore.QDataStream(byteArray,QtCore.qiodevice.writeonly)
            # implement writing to datastream 
            for i,index in enumerate(indexes):
                # encode index
                dataStream.writeInt16(index.row())
                dataStream.writeInt16(index.column())
                # encode item
                dataStream = self.encode_item_to_stream(
                    item=index.data(generic_roles.ItemDaTarole)
                    stream = dataStream
                )
    
            return byteArray
    
        def encode_item_to_stream(self,item,stream:QtCore.QDataStream) -> QtCore.QDataStream:
            """can be overridden by subclasses of the generic drag drop model to allow for custom item serialization"""
            pass
    
        def decode_data(self,data:QtCore.QMimeData)-> list: 
            # decoding the dropped data
            encodedData = data.data("application/x-generic-drag-drop")
            stream = QtCore.QDataStream(encodedData,QtCore.qiodevice.ReadOnly)
    
            source_indexes = []
            decoded_items = []
            while not stream.atEnd():
                # decode index
                row = stream.readInt16()
                col = stream.readInt16()
                source_indexes.append((row,col))
                # decode item
                decoded_items.append(stream)
    
            return indexes,decoded_items
    
        def decode_item_from_stream(self,stream:QtCore.QDataStream):
            """can be overridden by subclasses of the generic drag drop model to allow for custom item serialization"""
            pass
    

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)