在 Pyside 中,为啥在处理信号后发出大于 0x7FFFFFFF 的整数会导致“OverflowError”?
Posted
技术标签:
【中文标题】在 Pyside 中,为啥在处理信号后发出大于 0x7FFFFFFF 的整数会导致“OverflowError”?【英文标题】:In Pyside, why does emiting an integer > 0x7FFFFFFF result in "OverflowError" after the signal is processed?在 Pyside 中,为什么在处理信号后发出大于 0x7FFFFFFF 的整数会导致“OverflowError”? 【发布时间】:2012-05-26 00:48:45 【问题描述】:我正在尝试使用具有 0 - 2^32-1 范围内的大整数的信号/槽。我发现了一些奇怪的东西——一旦我发出 > 7FFFFFFF 边界,我会在插槽运行之后 抛出 OverflowError 异常。如果我或 QT 在 C 或 C++ 等另一种语言中明确使用带符号的 32 位整数,我可能会预料到这种溢出——因为我们都知道 0x80000000 在 2s 补码表示法中回绕回 -2^31。但是在 python 中,它只有 2^32 没有包装。我在编写代码时的假设是这是 python 并且内置的 int 可以变得非常大(可能是任意的?)并且我不需要明确地定义为 32 位或 64 位或有符号/无符号的东西。这一切都会奏效。
下面的代码演示了我所看到的(Python 2.7.2(64 位)、Pyside 1.1.0、Windows 7)
from PySide.QtCore import *
@Slot(int)
def say(i):
print "Say %i" % i
class Communicate(QObject):
speak = Signal(int)
someone = Communicate()
someone.speak.connect(say)
someone.speak.emit(0x7FFFFFFF) #works fine
someone.speak.emit(0x80000000) #OverflowError after slot "say" runs
say(0x80000000) #works fine
确切的输出是:
说 2147483647 说-2147483648 溢出错误 说2147483648-
为什么 Qt 似乎将整数类型的信号/槽视为处理带符号的 32 位整数而不是 python 内置整数?
如果这是 Qt 的限制,我可以做些什么来将 int 标记为无符号或确保 QT 可以处理 > 0x7FFFFFFF 的整数?
【问题讨论】:
“我们都知道 0x80000000 回绕到 -1” - 我不认为它会改变任何东西,但 0xfffffffff 是 -1 而 0x80000000 是 2s 补码中最大的 32 位负整数。 @andrewcooke 你是对的,我解决了这个问题。 显然 Qt 做出了不适合 Python 的假设。 另外,在 Python 中,0x80000000 不会回绕成负数,即使在 C 级别也是如此。 在我看来它是在说“不要那样做!”是否有理由需要使用这些值?您只是在任何复杂的环境中自找麻烦,尤其是在涉及多种语言的环境中。 【参考方案1】:我主要是 PyQt 用户,但我相信行为是相似的。信号定义中的int
映射到 4 字节整数(正如 Qt 理解的 int
)。
一种可能的解决方案是强制信号发出 Python 对象。这有效:
class Communicate(QObject):
speak = Signal(object)
但请注意,如果您将此信号连接到需要 Qt 版本的 int
(例如 QtGui.QSpinBox.setMaximum
)的插槽,您将看到相同的行为。除此之外,纯粹在 Python 端使用这个信号应该没问题。
【讨论】:
谢谢。您是否有链接说信号定义中的 int 与 QT(或 C++)的 int 概念相关联,而不与 python 相关? @DougT。 :PyQt 做到了that way。具体来说:“发出信号时,如果可能,任何参数都将转换为 C++ 类型。” 和PySide says,它实现了相同的接口。int
具有直接的 C++ 表示形式。
附加文档,所有新式信号槽中的例子都指向“int”,意思是C整数qt-project.org/wiki/Signals_and_Slots_in_PySide以上是关于在 Pyside 中,为啥在处理信号后发出大于 0x7FFFFFFF 的整数会导致“OverflowError”?的主要内容,如果未能解决你的问题,请参考以下文章