Hi,
thanks for the answers!
I didn't read about the default signals in the archive, but surely will dig
them out when I find some time.
The test cases were attached in the original email, I've re-added them to this
email and hope that some may be of use.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import unittest
import PySide.QtCore as QtCore
import PySide.QtGui as QtGui
from functools import partial
def getApplication():
app = QtCore.QCoreApplication.instance()
if app is None:
app = QtGui.QApplication(sys.argv)
return app
app = getApplication()
class PythonMessage(object):
def __init__(self, message):
super(PythonMessage, self).__init__()
self._message = message
def __repr__(self):
return self._message
class PythonSignalTester(QtCore.QObject):
def __init__(self, parent=None):
super(PythonSignalTester, self).__init__(parent)
signal1 = QtCore.Signal('QVariant')
signal2 = QtCore.Signal(str, 'QVariant')
class NewSignalsAndSlotsTestCase(unittest.TestCase):
def __init__(self, *args, **kwargs):
super(NewSignalsAndSlotsTestCase, self).__init__(*args, **kwargs)
self._value1 = None
self._value1Int = None
self._value2 = None
@QtCore.Slot(int)
@QtCore.Slot(float)
@QtCore.Slot(str)
@QtCore.Slot('QVariant')
def slot1(self, value1):
self._value1 = value1
@QtCore.Slot(int)
def slot1Int(self, value1):
self._value1Int = value1
@QtCore.Slot(str, 'QVariant')
def slot2(self, value1, value2):
self._value1 = value1
self._value2 = value2
def testAutomaticType(self):
spinBox = QtGui.QSpinBox()
spinBox.valueChanged.connect(self.slot1Int)
spinBox.valueChanged.emit(1)
self.assertEqual(1, self._value1Int)
def testIntSignal1(self):
spinBox = QtGui.QSpinBox()
spinBox.valueChanged['int'].connect(self.slot1)
spinBox.valueChanged['int'].emit(1)
self.assertEqual(1, self._value1)
def testIntSignal2(self):
spinBox = QtGui.QSpinBox()
spinBox.valueChanged[int].connect(self.slot1)
spinBox.valueChanged[int].emit(2)
self.assertEqual(2, self._value1)
def testStrSignal1(self):
spinBox = QtGui.QSpinBox()
spinBox.valueChanged['QString'].connect(self.slot1)
spinBox.valueChanged['QString'].emit(u'1')
self.assertEqual(u'1', self._value1)
def testStrSignal2(self):
spinBox = QtGui.QSpinBox()
spinBox.valueChanged[str].connect(self.slot1)
spinBox.valueChanged[str].emit('2')
self.assertEqual('2', self._value1)
def testStrSignal3(self):
spinBox = QtGui.QSpinBox()
spinBox.valueChanged[unicode].connect(self.slot1)
spinBox.valueChanged[unicode].emit(u'3')
self.assertEqual(u'3', self._value1)
def testDoubleSignal1(self):
spinBox = QtGui.QDoubleSpinBox()
spinBox.valueChanged['double'].connect(self.slot1)
spinBox.valueChanged['double'].emit(1.0)
self.assertEqual(1.0, self._value1)
def testDoubleSignal2(self):
spinBox = QtGui.QDoubleSpinBox()
spinBox.valueChanged[float].connect(self.slot1)
spinBox.valueChanged[float].emit(2.0)
self.assertEqual(2.0, self._value1)
def testLambda(self):
func = lambda x='Button' : self.slot1(x)
button = QtGui.QPushButton("Button")
button.clicked.connect(func)
button.clicked.emit()
self.assertEqual('Button', self._value1)
def testPartial(self):
func = partial(self.slot1, 'False')
button = QtGui.QPushButton("Button")
button.clicked.connect(func)
button.clicked.emit()
self.assertEqual('Button', self._value1)
def testPythonSignal(self):
message = PythonMessage('This is a Python Object')
signalTester = PythonSignalTester()
signalTester.signal1.connect(self.slot1)
signalTester.signal1.emit(message)
self.assertEqual(repr(message), repr(self._value1))
self.assertEqual(message, self._value1)
def testMultiParameterSignal(self):
message = PythonMessage('bla')
signalTester = PythonSignalTester()
signalTester.signal2.connect(self.slot2)
signalTester.signal2.emit('foo', message)
self.assertEqual('foo', self._value1)
self.assertEqual(message, self._value2)
I'm pretty impressed of PySide and Qt I must say. After the 1.0 release PySide
should be elected to be the Python default GUI framework. PySide + Qt light
years ahead of the Tcl/Tk wrapper and the LGPL version should make it possible
licensing wise.
When this happens Apple will remove Python from the default install in Mac OS
X, though ;-)
/Christian
Am 16.12.2010 um 18:30 schrieb Hugo Parente Lima:
> On Sunday 12 December 2010 22:26:57 [email protected] wrote:
>> Hi,
>>
>> the documentation of how to use new style signals and slots is relatively
>> sparse, thus I wrote some test cases to determine what is to expect. I was
>> mostly looking at PyQt4 documentation when working with new style signals
>> and slots. These test cases raised two questions:
>>
>> 1) Even if a slot was annotated with @Slot(type) the connection is made
>> with all signals of the same name and not just the signal with the correct
>> overload type. The PyQt documentation states that it is using a default
>> overload in these situations. What is the right behavior in this case?
>>
>> @QtCore.Slot(int)
>> @QtCore.Slot('double')
>> @QtCore.Slot(str)
>> @QtCore.Slot('QVariant')
>> def slot1(self, value1):
>> self._value1 = value1
>>
>> @QtCore.Slot(int)
>> def slot1Int(self, value1):
>> self._value1Int = value1
>>
>> def testAutomaticType(self):
>> spinBox = QtGui.QSpinBox()
>> spinBox.valueChanged.connect(self.slot1Int)
>> spinBox.valueChanged.emit(1)
>> self.assertEqual(1, self._value1Int)
>
> As discussed in this mailing list you can't rely on the default signal,
> because it's chosen by PySide according to the order it appear on Qt headers
> and if Qt add another overload for a signal your program can break :-/.
>
>> 2) float is no valid type for double signals, although a Python float is a
>> C signed double. Should the Python type float be a valid type for signal
>> overrides?
>>
>> def testDoubleSignal2(self):
>> spinBox = QtGui.QDoubleSpinBox()
>> spinBox.valueChanged[float].connect(self.slot1)
>> spinBox.valueChanged[float].emit(2.0)
>> self.assertEqual(2.0, self._value1)
>
> Should be, all python primitives should be valid types for signals and slots.
>
>> The testPartial and testLambda methods are test cases for bug #542. In the
>> case of the clicked signal of a QPushButton, the optional signal parameter
>> "checked = false" seems to get passed along to slots that are partial or
>> lambda functions.
>
> Can you send to us your unit test? so we can check the failing tests and
> maybe
> add it to our test suite.
>
>> Test output
>> -----------
>>
>> Finding files...
>> ['/.../new_style_signals_slots.py'] ... done
>> Importing test modules ... done.
>>
>> testAutomaticSignalType
>> (new_style_signals_slots.NewSignalsAndSlotsTestCase) ... FAIL
>> testDoubleSignal1 (new_style_signals_slots.NewSignalsAndSlotsTestCase) ...
>> ok testDoubleSignal2 (new_style_signals_slots.NewSignalsAndSlotsTestCase)
>> ... ERROR testIntSignal1
>> (new_style_signals_slots.NewSignalsAndSlotsTestCase) ... ok testIntSignal2
>> (new_style_signals_slots.NewSignalsAndSlotsTestCase) ... ok testLambda
>> (new_style_signals_slots.NewSignalsAndSlotsTestCase) ... FAIL
>> testMultiParameters (new_style_signals_slots.NewSignalsAndSlotsTestCase)
>> ... ok testPartial (new_style_signals_slots.NewSignalsAndSlotsTestCase)
>> ... FAIL TypeErrortestPythonSignal
>> (new_style_signals_slots.NewSignalsAndSlotsTestCase) ... ok testStrSignal1
>> (new_style_signals_slots.NewSignalsAndSlotsTestCase) ... ok testStrSignal2
>> (new_style_signals_slots.NewSignalsAndSlotsTestCase) ... : slot1() takes
>> exactly 2 arguments (3 given) ok
>> testStrSignal3 (new_style_signals_slots.NewSignalsAndSlotsTestCase) ... ok
>>
>> ======================================================================
>> ERROR: testDoubleSignal2
>> (new_style_signals_slots.NewSignalsAndSlotsTestCase)
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>> File "/.../new_style_signals_slots.py", line 105, in testDoubleSignal2
>> spinBox.valueChanged[float].connect(self.slot1)
>> IndexError: Signature valueChanged(qreal) not found for signal:
>> valueChanged
>>
>> ======================================================================
>> FAIL: testAutomaticSignalType
>> (new_style_signals_slots.NewSignalsAndSlotsTestCase)
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>> File "/.../new_style_signals_slots.py", line 65, in
>> testAutomaticSignalType self.assertEqual(1, self._value1Int)
>> AssertionError: 1 != u''
>>
>> ======================================================================
>> FAIL: testLambda (new_style_signals_slots.NewSignalsAndSlotsTestCase)
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>> File "/.../new_style_signals_slots.py", line 114, in testLambda
>> self.assertEqual('Button', self._value1)
>> AssertionError: 'Button' != True
>>
>> ======================================================================
>> FAIL: testPartial (new_style_signals_slots.NewSignalsAndSlotsTestCase)
>> ----------------------------------------------------------------------
>> Traceback (most recent call last):
>> File "/.../new_style_signals_slots.py", line 121, in testPartial
>> self.assertEqual('Button', self._value1)
>> AssertionError: 'Button' != None
>>
>> ----------------------------------------------------------------------
>> Ran 12 tests in 0.013s
>>
>> FAILED (failures=3, errors=1)
>>
>>
>> The test cases are attached.
>
> --
> Hugo Parente Lima
> INdT - Instituto Nokia de Tecnologia
_______________________________________________
PySide mailing list
[email protected]
http://lists.openbossa.org/listinfo/pyside