如何防止PySide信号和插槽尝试将二进制字符串数据转换为Unicode?

时间:2014-07-07 22:28:31

标签: python python-2.7 pyside signals-slots

PySide信号和插槽似乎在静默地将我的二进制字符串转换为unicode。我怎么能避免呢?或者,如何在没有PySide变异的情况下通过信号槽接口传递二进制数据?

from PySide import QtCore

class Thingy(QtCore.QObject):
    data = QtCore.Signal(str)

@QtCore.Slot(str)
def printdata(x):
    print "type=%s, x=%s" % (type(x), x.__repr__())

thingy = Thingy()
thingy.data.connect(printdata)

for data in ('Hey', '\x55\xaa'):
    printdata(data)
    thingy.data.emit(data)

打印出来:

type=<type 'str'>, x='Hey'
type=<type 'unicode'>, x=u'Hey'
type=<type 'str'>, x='U\xaa'
type=<type 'unicode'>, x=u'U\xaa'

2 个答案:

答案 0 :(得分:4)

您只需用object替换信号和插槽中的类型说明符,PySide就不会调用任何转换。

from PySide import QtCore

class Thingy(QtCore.QObject):
    data = QtCore.Signal(object)

@QtCore.Slot(object)
def printdata(x):
    print "type=%s, x=%s" % (type(x), x.__repr__())

thingy = Thingy()
thingy.data.connect(printdata)

for data in ('Hey', '\x55\xaa'):
    printdata(data)
    thingy.data.emit(data)

给出

type=<type 'str'>, x='Hey'
type=<type 'str'>, x='Hey'
type=<type 'str'>, x='U\xaa'
type=<type 'str'>, x='U\xaa'

这允许您发送二进制数据。

答案 1 :(得分:1)

我正在为python 2编写。在python 3中,这种情况可能更明智(但我不确定)。

在Qt中,字符串类为QString。当pyside想要将QString 传递给python 时,它会选择unicode类型。这是一件好事,因为QString支持unicode。没有办法告诉Qt库,QString实际上应该是一个字节数组,所以一旦你的python str转换为QString,你就会得到一个unicode。从这里你可以看到,当你将str 传递给Qt 并且pyside将python str转换为QString时,问题确实发生了。

为什么pyside将python str转换为QString而不是eg。 QByteArray?在python 2中,字节数组没有单独的类型,因此str作为字节数组和文本执行双重任务。我的猜测是QString是默认值,因为str 通常代表文本。

如果你有ASCII文本,最简单的解决方案就是在你的插槽开头调用str()

@QtCore.Slot(str)
def printdata(x):
    x = str(x)
    print "type=%s, x=%s" % (type(x), x.__repr__())

但是,正如您在问题中所说,您有二进制数据,所以这不起作用。一种解决方案是告诉信号接受您自己的自定义类型:

class Thingy(QtCore.QObject):
    data = pyqtSignal(<your custom byte array type>)

然后你可以创建自己的字节数组类型,它使用str(确保它是一个新的样式类)。

最后,你可以使用QByteArray:

class Thingy(QtCore.QObject):
    data = pyqtSignal(QByteArray)