Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Pyside, why does emiting an integer > 0x7FFFFFFF result in "OverflowError" after the signal is processed?

I'm attempting to use signals/slots with large integers ranging from 0 - 2^32-1. I've discovered something a little weird -- once I emit > 7FFFFFFF boundary, I get OverflowError exceptions thrown after the slot is run. I might expect this kind of overflow if I or QT were explicitly using a signed 32 bit integer in another language like C or C++--as we all know 0x80000000 wraps back to -2^31 in 2s complement notation. In python though, its just 2^32 without wrapping. My assumption when writing the code though was that this is python and that the built-in int can grow very large (maybe arbitrarilly so?) and that I don't explicitly need to define something as 32 or 64 bit or signed/unsigned. It would all just work.

The code below demonstrates what I'm seeing (Python 2.7.2 (64 bit), 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

The exact output is:

Say 2147483647
Say -2147483648
OverflowError
Say 2147483648
  1. Why does Qt seem to treat the signals/slots of type integer as if its dealing with signed 32 bit integers and not python built-in ints?
  2. If this is a restriction of Qt, what can I do to mark the int as unsigned or make sure QT can deal with integers > 0x7FFFFFFF?
like image 327
Doug T. Avatar asked May 26 '12 00:05

Doug T.


1 Answers

I'm mostly a PyQt user, but I believe the behavior is similar. int in signal definition is mapped to 4-byte integer (as Qt understands an int).

One possible solution is to force the signal to emit a Python object. This works:

class Communicate(QObject):
    speak = Signal(object)

But be aware that, if you connect this signal to a slot that expects a Qt's version of int (for example QtGui.QSpinBox.setMaximum) you'll see the same behavior. Other than that, using this signal purely on the Python side should be fine.

like image 169
Avaris Avatar answered Oct 20 '22 23:10

Avaris