重写QIODevice子类中的readData会返回错误的结果

Overriding readData in QIODevice subclass returns incorrect result

本文关键字:返回 错误 结果 readData 子类 重写 QIODevice      更新时间:2023-10-16

我试图在PySide中子类化QFile以实现自定义读取行为。然而,如下面的简化代码所示,即使子类的readData实现只是调用父类的readData函数,返回的数据也是不正确的。子类化其他qiodevice(如QBuffer)也会导致不正确的返回值。是否有人成功子类化了QIODevice?

from PySide import QtCore
class FileChild1(QtCore.QFile):
    pass
class FileChild2(QtCore.QFile):
    def readData(self, maxlen):
        return super(FileChild2, self).readData(maxlen)

f1 = FileChild1('test.txt')
f1.open(QtCore.QIODevice.ReadWrite|QtCore.QIODevice.Truncate)
f1.write('Test text for testing')
f1.seek(0)
print 'FileChild1: ', repr(f1.read(50))
f2 = FileChild2('test2.txt')
f2.open(QtCore.QIODevice.ReadWrite|QtCore.QIODevice.Truncate)
f2.write('Test text for testing')
f2.seek(0)
print 'FileChild2: ', repr(f2.read(50))
>>> FileChild1:  PySide.QtCore.QByteArray('Test text for testing')
>>> FileChild2:  PySide.QtCore.QByteArray('─ Q ►│A☻ @  p¼a☻Test text for testingx00x00x00x00x00x00x00x00x00x00x00x00x00')

我用PyQt 4.8和PyQt 4.9和Python 2.7.2/Qt 4.8.0测试了你的脚本,在这两种情况下,它都会产生以下输出:

FileChild1:  'Test text for testing'
FileChild2:  'Test text for testing'

所以readData返回一个字节字符串,按照PyQt4文档。

使用PySide 1.0.9与Python 2.7.2/Qt 4.8.0,我得到这个输出:

FileChild1:  PySide.QtCore.QByteArray('Test text for testing')
FileChild2:  PySide.QtCore.QByteArray('')

不确定为什么PyQt4和PySide的返回类型不同,但PySide显然存在某种错误。

这里有一个bug报告,看起来可能有点相关,但不是最近的(PySide 1.0.7)。

PySide的错误来自shiboken, qint64在QIODevice中被用作偏移类型,但在Python 2中qint64被映射为"int"。X,不是"长"。当qint64的值大于qint32时,读取该值将导致Python 2。抛出OverflowError。当使用qint64作为Slot/Signal/Property或任何Qt元类型来与Python通信Qt c++代码时,也会发生类似的OverflowError。

我也在寻找绕过这个问题的解决方案。

在Qt5和PySide2上也非常有效。我们正在调查。