2012-05-26 5 views
5

Sto tentando di utilizzare segnali/slot con numeri interi grandi compresi tra 0 e 2^32-1. Ho scoperto qualcosa di strano: una volta emesso il limite> 7FFFFFFF, ottengo le eccezioni OverflowError generate dopo lo lo slot viene eseguito. Potrei aspettarmi questo tipo di overflow se io o QT usassimo esplicitamente un intero con segno a 32 bit in un'altra lingua come C o C++ - come tutti sappiamo 0x80000000 torna a -2^31 in notazione complemento a 2 secondi. In Python però, è solo 2^32 senza wrapping. Il mio presupposto quando scrivevo il codice era che si trattava di python e che il built-in int può diventare molto grande (forse arbitrariamente così?) E che non ho bisogno di definire esplicitamente qualcosa come 32 o 64 bit o firmato/non firmato. Funzionerebbe tutto solo.In Pyside, perché l'emettere un intero> 0x7FFFFFFF genera "OverflowError" dopo che il segnale è stato elaborato?

Il seguente codice illustra quello che sto vedendo (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 

L'uscita esatta è:

 
Say 2147483647 
Say -2147483648 
OverflowError 
Say 2147483648 
  1. Perché Qt sembra trattare i segnali/slot di tipo intero come se si trattasse di interi a 32 bit con segno e non di inti incorporati in python?
  2. Se questa è una limitazione di Qt, cosa posso fare per contrassegnare l'int come non firmato o accertarmi che QT possa gestire interi> 0x7FFFFFFF?
+1

"tutti sappiamo 0x80000000 torna a -1" - non penso che cambi nulla, ma 0xfffffffff è -1 e 0x80000000 è il numero intero a 32 bit negativo maggiore nel complemento a 2. –

+0

@erewcooke sei corretto, ho risolto la domanda. –

+3

Ovviamente Qt formula assunzioni che non si adattano a Python. –

risposta

5

Sono principalmente un utente PyQt, ma credo che il comportamento sia simile. int nella definizione del segnale è mappato su intero a 4 byte (poiché Qt comprende uno int).

Una possibile soluzione è forzare il segnale ad emettere un oggetto Python. Questo funziona:

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

ma essere consapevoli che, se ci si connette questo segnale a uno slot che si aspetta la versione di un Qt di int (ad esempio QtGui.QSpinBox.setMaximum) si vedrà lo stesso comportamento. Oltre a questo, usare questo segnale esclusivamente sul lato Python dovrebbe andare bene.

+0

Grazie. Avete un link che dice int nella definizione del segnale è legato alla nozione di QT (o C++) di un int e non a pitoni? –

+1

@DougT. : PyQt lo fa [in questo modo] (http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/new_style_signals_slots.html). In particolare: _ "Quando viene emesso un segnale, eventuali argomenti vengono convertiti in tipi C++, se possibile." _ E [PySide dice] (http://www.pyside.org/docs/pyside/PySide/QtCore/Signal.html) , implementa la stessa interfaccia. 'int' ha una rappresentazione C++ diretta. – Avaris

+0

Documentazione aggiuntiva, tutti gli esempi in segnali e slot di tipo nuovo puntano a "int" che significa C intero http://qt-project.org/wiki/Signals_and_Slots_in_PySide –

Problemi correlati