2012-05-26 10 views
5

Estoy intentando utilizar señales/ranuras con números enteros grandes que van de 0 a 2^32-1. Descubrí algo un poco raro: una vez que emito el límite 7FFFFFFF, recibo excepciones OverflowError lanzadas después de se ejecuta la ranura. Podría esperar este tipo de desbordamiento si I o QT estuvieran usando explícitamente un entero de 32 bits con signo en otro idioma como C o C++, ya que todos sabemos que 0x80000000 vuelve a -2^31 en notación de complemento 2s. En Python, sin embargo, es solo 2^32 sin envolver. Mi suposición al escribir el código fue que esto es python y que el int interno puede crecer muy grande (¿tal vez arbitrariamente?) Y que no necesito definir explícitamente algo como 32 o 64 bits o firmado/sin firmar. Todo funcionaría.En Pyside, ¿por qué emitir un entero> 0x7FFFFFFF da como resultado "OverflowError" después de procesar la señal?

El código siguiente muestra lo que estoy viendo (Python 2.7.2 (64 bits), 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 

La salida exacta es:

 
Say 2147483647 
Say -2147483648 
OverflowError 
Say 2147483648 
  1. ¿Por qué Qt parece tratar las señales/ranuras de tipo entero como si se tratara de enteros de 32 bits con signo y no de intes incorporados en Python?
  2. Si esto es una restricción de Qt, ¿qué puedo hacer para marcar el int como unsigned o asegurarme de que QT pueda tratar con enteros> 0x7FFFFFFF?
+1

"todos sabemos 0x80000000 envuelve a -1" - no creo que cambie nada, pero 0xfffffffff es -1 y 0x80000000 es el mayor entero negativo de 32 bits en complemento a 2s. –

+0

@andrewcooke tienes razón, he resuelto la pregunta. –

+3

Obviamente Qt hace suposiciones que no se ajustan a Python. –

Respuesta

5

Soy principalmente un usuario de PyQt, pero creo que el comportamiento es similar. int en la definición de la señal se asigna a un entero de 4 bytes (ya que Qt comprende un int).

Una posible solución es forzar a la señal a emitir un objeto Python. Esto funciona:

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

Pero tenga en cuenta que, si se conecta esta señal a una ranura que espera que la versión de un cuarto de galón de int (por ejemplo QtGui.QSpinBox.setMaximum) verá el mismo comportamiento. Aparte de eso, usar esta señal puramente en el lado de Python debería estar bien.

+0

Gracias. ¿Tiene un enlace que dice que int en definición de señal está relacionado con la noción QT (o C++) de un int y no de pitones? –

+1

@DougT. : PyQt lo hace [de esa manera] (http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/new_style_signals_slots.html). Específicamente: _ "Cuando se emite una señal, cualquier argumento se convierte a C++ si es posible". _ Y [dice PySide] (http://www.pyside.org/docs/pyside/PySide/QtCore/Signal.html) , implementa la misma interfaz. 'int' tiene una representación directa de C++. – Avaris

+0

Documentación adicional, todos los ejemplos en las señales de estilo nuevo y las ranuras señalan en "int", que significa C entero http://qt-project.org/wiki/Signals_and_Slots_in_PySide –

Cuestiones relacionadas