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

Python 如何防止PySide信号和插槽尝试将二进制字符串数据转换为Unicode?,python,python-2.7,pyside,signals-slots,Python,Python 2.7,Pyside,Signals Slots,PySide信号和插槽似乎在默默地将二进制字符串转换为unicode。我怎样才能避免呢?或者,如何通过signals-slots接口传递二进制数据而不使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

PySide信号和插槽似乎在默默地将二进制字符串转换为unicode。我怎样才能避免呢?或者,如何通过signals-slots接口传递二进制数据而不使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'
type=,x='Hey'
type=,x=u'Hey'
类型=,x='U\xaa'
类型=,x=u'u\xaa'

我是为python 2编写的。在Python3中,这种情况可能更合理(但我不确定)

在Qt中,string类是
QString
。当pyside想要将QString传递到python中时,它选择
unicode
类型。这是一件好事,因为QString支持unicode。没有办法告诉Qt libs QString实际上应该是一个字节数组,因此一旦python
str
被转换为QString,您将得到一个unicode。从这一点可以看出,当您将str传递到Qt,pyside将python str转换为QString时,问题确实发生了

为什么pyside将python str转换为QString而不是QByteArray?在Python2中,字节数组没有单独的类型,因此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>)

您只需将信号和插槽中的类型说明符替换为
对象
,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=,x='Hey'
type=,x='嘿'
类型=,x='U\xaa'
类型=,x='U\xaa'

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

“\x55\xaa”案例有什么意义?因为它是二进制数据。55AA是一个常见的测试用例(也是一个导致我的部分代码爆炸的测试用例)。我能做些什么来澄清我的答案或帮助它变得更适用吗?我真的有二进制数据(我想我在我的问题中对此很清楚)。“最简单的解决方案是在插槽的开头调用str():--不,因为那时我遇到了一些疯狂的Unicode/ASCII问题。我可以通过在Python类中包装我的类型来解决问题。现在我知道了QByteArray,我将使用它。:-)@贾森:是的,如果你有二进制,QByteArray是个不错的选择。我很抱歉没有理解您处理的是二进制字符串。我在编辑这个问题时考虑到了这一点。你真的试过这个吗?@DanialSank我不只是猜测了指示的输出。我被你的答案中的“(至少我希望如此)”弄糊涂了。@DanialSank哦,你说得对,这听起来可能很奇怪。问题是,我对PyScript绑定的内部工作和Qt的C++部分了解得不够。我认为原则上他们只需要提供一个通用的引用,类型规范只是为了额外的类型安全,但是如果您选择str,那么就需要进行转换,所以这可能是不对的。所以我测试了它的工作原理,我只是不知道它为什么工作,明白了。我想你的答案比我的好。OP应该接受它。
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'