aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/tests/signals
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/tests/signals')
-rw-r--r--sources/pyside6/tests/signals/CMakeLists.txt7
-rw-r--r--sources/pyside6/tests/signals/anonymous_slot_leak_test.py55
-rw-r--r--sources/pyside6/tests/signals/args_dont_match_test.py12
-rw-r--r--sources/pyside6/tests/signals/bug_311.py5
-rw-r--r--sources/pyside6/tests/signals/bug_312.py29
-rw-r--r--sources/pyside6/tests/signals/bug_319.py5
-rw-r--r--sources/pyside6/tests/signals/bug_79.py7
-rw-r--r--sources/pyside6/tests/signals/decorators_test.py11
-rw-r--r--sources/pyside6/tests/signals/invalid_callback_test.py6
-rw-r--r--sources/pyside6/tests/signals/lambda_gui_test.py64
-rw-r--r--sources/pyside6/tests/signals/lambda_test.py110
-rw-r--r--sources/pyside6/tests/signals/leaking_signal_test.py3
-rw-r--r--sources/pyside6/tests/signals/multiple_connections_gui_test.py46
-rw-r--r--sources/pyside6/tests/signals/multiple_connections_test.py33
-rw-r--r--sources/pyside6/tests/signals/pysignal_test.py172
-rw-r--r--sources/pyside6/tests/signals/qobject_callable_connect_test.py45
-rw-r--r--sources/pyside6/tests/signals/qobject_destroyed_test.py2
-rw-r--r--sources/pyside6/tests/signals/qobject_sender_test.py31
-rw-r--r--sources/pyside6/tests/signals/ref01_test.py2
-rw-r--r--sources/pyside6/tests/signals/ref02_test.py11
-rw-r--r--sources/pyside6/tests/signals/ref03_test.py1
-rw-r--r--sources/pyside6/tests/signals/ref04_test.py11
-rw-r--r--sources/pyside6/tests/signals/ref05_test.py11
-rw-r--r--sources/pyside6/tests/signals/ref06_test.py11
-rw-r--r--sources/pyside6/tests/signals/segfault_proxyparent_test.py24
-rw-r--r--sources/pyside6/tests/signals/self_connect_test.py25
-rw-r--r--sources/pyside6/tests/signals/short_circuit_test.py38
-rw-r--r--sources/pyside6/tests/signals/signal2signal_connect_test.py61
-rw-r--r--sources/pyside6/tests/signals/signal_across_threads.py8
-rw-r--r--sources/pyside6/tests/signals/signal_autoconnect_test.py2
-rw-r--r--sources/pyside6/tests/signals/signal_connectiontype_support_test.py15
-rw-r--r--sources/pyside6/tests/signals/signal_emission_gui_test.py196
-rw-r--r--sources/pyside6/tests/signals/signal_emission_test.py57
-rw-r--r--sources/pyside6/tests/signals/signal_manager_refcount_test.py8
-rw-r--r--sources/pyside6/tests/signals/signal_newenum_test.py50
-rw-r--r--sources/pyside6/tests/signals/signal_object_test.py4
-rw-r--r--sources/pyside6/tests/signals/signal_signature_test.py15
-rw-r--r--sources/pyside6/tests/signals/signal_with_primitive_type_test.py4
-rw-r--r--sources/pyside6/tests/signals/signals.pyproject19
-rw-r--r--sources/pyside6/tests/signals/slot_reference_count_test.py12
-rw-r--r--sources/pyside6/tests/signals/static_metaobject_test.py30
41 files changed, 743 insertions, 515 deletions
diff --git a/sources/pyside6/tests/signals/CMakeLists.txt b/sources/pyside6/tests/signals/CMakeLists.txt
index 14936869f..ff342adc7 100644
--- a/sources/pyside6/tests/signals/CMakeLists.txt
+++ b/sources/pyside6/tests/signals/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
PYSIDE_TEST(args_dont_match_test.py)
PYSIDE_TEST(bug_79.py)
PYSIDE_TEST(bug_189.py)
@@ -13,6 +16,7 @@ PYSIDE_TEST(leaking_signal_test.py)
PYSIDE_TEST(multiple_connections_gui_test.py)
PYSIDE_TEST(multiple_connections_test.py)
PYSIDE_TEST(pysignal_test.py)
+PYSIDE_TEST(qobject_callable_connect_test.py)
PYSIDE_TEST(qobject_destroyed_test.py)
PYSIDE_TEST(qobject_receivers_test.py)
PYSIDE_TEST(qobject_sender_test.py)
@@ -29,11 +33,12 @@ PYSIDE_TEST(signal2signal_connect_test.py)
PYSIDE_TEST(signal_across_threads.py)
PYSIDE_TEST(signal_autoconnect_test.py)
PYSIDE_TEST(signal_connectiontype_support_test.py)
-PYSIDE_TEST(signal_enum_test.py)
PYSIDE_TEST(signal_emission_gui_test.py)
PYSIDE_TEST(signal_emission_test.py)
+PYSIDE_TEST(signal_enum_test.py)
PYSIDE_TEST(signal_func_test.py)
PYSIDE_TEST(signal_manager_refcount_test.py)
+PYSIDE_TEST(signal_newenum_test.py)
PYSIDE_TEST(signal_number_limit_test.py)
PYSIDE_TEST(signal_object_test.py)
PYSIDE_TEST(signal_signature_test.py)
diff --git a/sources/pyside6/tests/signals/anonymous_slot_leak_test.py b/sources/pyside6/tests/signals/anonymous_slot_leak_test.py
new file mode 100644
index 000000000..560a08659
--- /dev/null
+++ b/sources/pyside6/tests/signals/anonymous_slot_leak_test.py
@@ -0,0 +1,55 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from functools import partial
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QWidget
+from helper.usesqapplication import UsesQApplication
+
+
+have_debug = hasattr(sys, "gettotalrefcount")
+
+
+class LeakerLambda():
+ def __init__(self, widget):
+ widget.windowIconChanged.connect(lambda *args: None)
+
+
+class LeakerFunctoolsPartial():
+ def __init__(self, widget):
+ widget.windowIconChanged.connect(partial(int, 0))
+
+
+class TestBugPYSIDE2299(UsesQApplication):
+ def leak(self, leaker):
+ widget = QWidget()
+
+ # Warm-up
+ leaker(widget)
+
+ refs_before = sys.gettotalrefcount()
+ for _ in range(1000):
+ leaker(widget)
+ refs_after = sys.gettotalrefcount()
+
+ self.assertAlmostEqual(refs_after - refs_before, 0, delta=10)
+
+ @unittest.skipUnless(have_debug, "You need a debug build")
+ def test_lambda(self):
+ self.leak(LeakerLambda)
+
+ @unittest.skipUnless(have_debug, "You need a debug build")
+ def test_functools_partial(self):
+ self.leak(LeakerFunctoolsPartial)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/args_dont_match_test.py b/sources/pyside6/tests/signals/args_dont_match_test.py
index e200cedbc..4f56be348 100644
--- a/sources/pyside6/tests/signals/args_dont_match_test.py
+++ b/sources/pyside6/tests/signals/args_dont_match_test.py
@@ -11,7 +11,11 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL
+from PySide6.QtCore import QObject, Signal
+
+
+class Sender(QObject):
+ the_signal = Signal(int, int, int)
class ArgsDontMatch(unittest.TestCase):
@@ -21,9 +25,9 @@ class ArgsDontMatch(unittest.TestCase):
def testConnectSignalToSlotWithLessArgs(self):
self.ok = False
- obj1 = QObject()
- QObject.connect(obj1, SIGNAL('the_signal(int, int, int)'), self.callback)
- obj1.emit(SIGNAL('the_signal(int, int, int)'), 1, 2, 3)
+ obj1 = Sender()
+ obj1.the_signal.connect(self.callback)
+ obj1.the_signal.emit(1, 2, 3)
self.assertTrue(self.ok)
diff --git a/sources/pyside6/tests/signals/bug_311.py b/sources/pyside6/tests/signals/bug_311.py
index 5f8af81c1..e27476172 100644
--- a/sources/pyside6/tests/signals/bug_311.py
+++ b/sources/pyside6/tests/signals/bug_311.py
@@ -12,7 +12,7 @@ from init_paths import init_test_paths
init_test_paths(False)
from PySide6.QtCore import QDate, QObject, Signal
-from helper.usesqcoreapplication import UsesQCoreApplication
+from helper.usesqapplication import UsesQApplication
class DerivedDate(QDate):
@@ -26,7 +26,7 @@ class Emitter(QObject):
tupleSignal = Signal(tuple)
-class SignaltoSignalTest(UsesQCoreApplication):
+class SignaltoSignalTest(UsesQApplication):
def myCb(self, dt):
self._dt = dt
@@ -52,4 +52,3 @@ class SignaltoSignalTest(UsesQCoreApplication):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/bug_312.py b/sources/pyside6/tests/signals/bug_312.py
index de1a2f6a8..80d56a020 100644
--- a/sources/pyside6/tests/signals/bug_312.py
+++ b/sources/pyside6/tests/signals/bug_312.py
@@ -11,44 +11,29 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL
+from PySide6.QtCore import QObject, Signal
MAX_LOOPS = 5
MAX_OBJECTS = 200
-class Dummy(object):
- def __init__(self, parent):
- self._parent = parent
-
- def callback(self):
- self._called = True
+class Sender(QObject):
+ fire = Signal()
class MultipleSlots(unittest.TestCase):
def myCB(self):
self._count += 1
- """
- def testUnboundSignal(self):
- o = QObject()
- self._count = 0
- for i in range(MAX_OBJECTS):
- QObject.connect(o, SIGNAL("fire()"), lambda: self.myCB())
-
- o.emit(SIGNAL("fire()"))
- self.assertEqual(self._count, MAX_OBJECTS)
-
- """
def testDisconnectCleanup(self):
for c in range(MAX_LOOPS):
self._count = 0
self._senders = []
for i in range(MAX_OBJECTS):
- o = QObject()
- QObject.connect(o, SIGNAL("fire()"), lambda: self.myCB())
+ o = Sender()
+ o.fire.connect(lambda: self.myCB())
self._senders.append(o)
- o.emit(SIGNAL("fire()"))
+ o.fire.emit()
self.assertEqual(self._count, MAX_OBJECTS)
@@ -58,5 +43,3 @@ class MultipleSlots(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
-
diff --git a/sources/pyside6/tests/signals/bug_319.py b/sources/pyside6/tests/signals/bug_319.py
index aaa5ea991..657733afb 100644
--- a/sources/pyside6/tests/signals/bug_319.py
+++ b/sources/pyside6/tests/signals/bug_319.py
@@ -12,7 +12,7 @@ from init_paths import init_test_paths
init_test_paths(False)
from PySide6.QtCore import QObject, Signal, Slot
-from helper.usesqcoreapplication import UsesQCoreApplication
+from helper.usesqapplication import UsesQApplication
class Listener(QObject):
@@ -31,7 +31,7 @@ class Communicate(QObject):
speak = Signal(tuple)
-class SignaltoSignalTest(UsesQCoreApplication):
+class SignaltoSignalTest(UsesQApplication):
def testBug(self):
someone = Communicate()
someone2 = Listener()
@@ -45,4 +45,3 @@ class SignaltoSignalTest(UsesQCoreApplication):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/bug_79.py b/sources/pyside6/tests/signals/bug_79.py
index 54bd1f076..77ac621d5 100644
--- a/sources/pyside6/tests/signals/bug_79.py
+++ b/sources/pyside6/tests/signals/bug_79.py
@@ -30,7 +30,7 @@ class ConnectTest(unittest.TestCase):
def testNoLeaks_ConnectAndDisconnect(self):
self._called = None
- app = QApplication([])
+ app = QApplication([]) # noqa: F841
o = QTreeView()
o.setModel(QStandardItemModel())
o.selectionModel().destroyed.connect(self.callback)
@@ -38,6 +38,11 @@ class ConnectTest(unittest.TestCase):
gc.collect()
# if this is no debug build, then we check at least that
# we do not crash any longer.
+ for idx in range(200):
+ # PYSIDE-2230: Warm-up is necessary before measuring, because
+ # the code changes the constant parts after some time.
+ o.selectionModel().destroyed.connect(self.callback)
+ o.selectionModel().destroyed.disconnect(self.callback)
if not skiptest:
total = gettotalrefcount()
for idx in range(1000):
diff --git a/sources/pyside6/tests/signals/decorators_test.py b/sources/pyside6/tests/signals/decorators_test.py
index 5b3b54690..b29339ee4 100644
--- a/sources/pyside6/tests/signals/decorators_test.py
+++ b/sources/pyside6/tests/signals/decorators_test.py
@@ -11,7 +11,11 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, Slot, SIGNAL, SLOT
+from PySide6.QtCore import QObject, Slot, Signal
+
+
+class Sender(QObject):
+ mySignal = Signal()
class MyObject(QObject):
@@ -57,9 +61,10 @@ class StaticMetaObjectTest(unittest.TestCase):
self.assertTrue(m.indexOfSlot('mySlot4(QString,int)') > 0)
def testEmission(self):
+ sender = Sender()
o = MyObject()
- o.connect(SIGNAL("mySignal()"), o, SLOT("mySlot()"))
- o.emit(SIGNAL("mySignal()"))
+ sender.mySignal.connect(o.mySlot)
+ sender.mySignal.emit()
self.assertTrue(o._slotCalledCount == 1)
def testResult(self):
diff --git a/sources/pyside6/tests/signals/invalid_callback_test.py b/sources/pyside6/tests/signals/invalid_callback_test.py
index 0d7e574ef..2788c1d1a 100644
--- a/sources/pyside6/tests/signals/invalid_callback_test.py
+++ b/sources/pyside6/tests/signals/invalid_callback_test.py
@@ -13,7 +13,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL
+from PySide6.QtCore import QObject
class InvalidCallback(unittest.TestCase):
@@ -34,10 +34,8 @@ class InvalidCallback(unittest.TestCase):
def testIntegerCb(self):
# Test passing an int as callback to QObject.connect
- self.assertRaises(TypeError, QObject.connect, self.obj,
- SIGNAL('destroyed()'), 42)
+ self.assertRaises(TypeError, self.obj.destroyed.connect, 42)
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/lambda_gui_test.py b/sources/pyside6/tests/signals/lambda_gui_test.py
index 45a6d6acf..2123e7206 100644
--- a/sources/pyside6/tests/signals/lambda_gui_test.py
+++ b/sources/pyside6/tests/signals/lambda_gui_test.py
@@ -12,43 +12,39 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL
-
-try:
- from PySide6.QtWidgets import QSpinBox, QPushButton
- hasQtGui = True
-except ImportError:
- hasQtGui = False
+from PySide6.QtWidgets import QSpinBox, QPushButton
from helper.usesqapplication import UsesQApplication
-if hasQtGui:
- class Control:
- def __init__(self):
- self.arg = False
-
- class QtGuiSigLambda(UsesQApplication):
-
- def testButton(self):
- # Connecting a lambda to a QPushButton.clicked()
- obj = QPushButton('label')
- ctr = Control()
- func = lambda: setattr(ctr, 'arg', True)
- obj.clicked.connect(func)
- obj.click()
- self.assertTrue(ctr.arg)
- QObject.disconnect(obj, SIGNAL('clicked()'), func)
-
- def testSpinButton(self):
- # Connecting a lambda to a QPushButton.clicked()
- obj = QSpinBox()
- ctr = Control()
- arg = 444
- func = lambda x: setattr(ctr, 'arg', 444)
- obj.valueChanged.connect(func)
- obj.setValue(444)
- self.assertEqual(ctr.arg, arg)
- QObject.disconnect(obj, SIGNAL('valueChanged(int)'), func)
+
+class Control:
+ def __init__(self):
+ self.arg = False
+
+
+class QtWidgetsSigLambda(UsesQApplication):
+
+ def testButton(self):
+ # Connecting a lambda to a QPushButton.clicked()
+ obj = QPushButton('label')
+ ctr = Control()
+ func = lambda: setattr(ctr, 'arg', True) # noqa: E731
+ obj.clicked.connect(func)
+ obj.click()
+ self.assertTrue(ctr.arg)
+ self.assertTrue(obj.clicked.disconnect(func))
+
+ def testSpinButton(self):
+ # Connecting a lambda to a QPushButton.clicked()
+ obj = QSpinBox()
+ ctr = Control()
+ arg = 444
+ func = lambda x: setattr(ctr, 'arg', 444) # noqa: E731
+ obj.valueChanged.connect(func)
+ obj.setValue(444)
+ self.assertEqual(ctr.arg, arg)
+ self.assertTrue(obj.valueChanged.disconnect(func))
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside6/tests/signals/lambda_test.py b/sources/pyside6/tests/signals/lambda_test.py
index cc4e61ca1..23fcdf5fa 100644
--- a/sources/pyside6/tests/signals/lambda_test.py
+++ b/sources/pyside6/tests/signals/lambda_test.py
@@ -7,18 +7,34 @@
import os
import sys
import unittest
+import weakref
from pathlib import Path
sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL, QProcess
+from PySide6.QtCore import QCoreApplication, QObject, Signal, SIGNAL, QProcess
-from helper.usesqcoreapplication import UsesQCoreApplication
+from helper.usesqapplication import UsesQApplication
-class Dummy(QObject):
+class Sender(QObject):
+ void_signal = Signal()
+ int_signal = Signal(int)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._delayed_int = 0
+
+ def emit_void(self):
+ self.void_signal.emit()
+
+ def emit_int(self, v):
+ self.int_signal.emit(v)
+
+
+class Receiver(QObject):
def __init__(self, *args):
super().__init__(*args)
@@ -28,45 +44,79 @@ class BasicCase(unittest.TestCase):
def testSimplePythonSignalNoArgs(self):
# Connecting a lambda to a simple python signal without arguments
- obj = Dummy()
- QObject.connect(obj, SIGNAL('foo()'),
- lambda: setattr(obj, 'called', True))
- obj.emit(SIGNAL('foo()'))
- self.assertTrue(obj.called)
+ receiver = Receiver()
+ sender = Sender()
+ sender.void_signal.connect(lambda: setattr(receiver, 'called', True))
+ sender.emit_void()
+ self.assertTrue(receiver.called)
def testSimplePythonSignal(self):
# Connecting a lambda to a simple python signal witharguments
- obj = Dummy()
+ receiver = Receiver()
+ sender = Sender()
+ arg = 42
+ sender.int_signal.connect(lambda x: setattr(receiver, 'arg', arg))
+ sender.emit_int(arg)
+ self.assertEqual(receiver.arg, arg)
+
+ def testSimplePythonSignalNoArgsString(self):
+ # Connecting a lambda to a simple python signal without arguments
+ receiver = Receiver()
+ sender = Sender()
+ QObject.connect(sender, SIGNAL('void_signal()'),
+ lambda: setattr(receiver, 'called', True))
+ sender.emit_void()
+ self.assertTrue(receiver.called)
+
+ def testSimplePythonSignalString(self):
+ # Connecting a lambda to a simple python signal witharguments
+ receiver = Receiver()
+ sender = Sender()
arg = 42
- QObject.connect(obj, SIGNAL('foo(int)'),
- lambda x: setattr(obj, 'arg', 42))
- obj.emit(SIGNAL('foo(int)'), arg)
- self.assertEqual(obj.arg, arg)
+ QObject.connect(sender, SIGNAL('int_signal(int)'),
+ lambda x: setattr(receiver, 'arg', arg))
+ sender.emit_int(arg)
+ self.assertEqual(receiver.arg, arg)
-class QtSigLambda(UsesQCoreApplication):
+class QtSigLambda(UsesQApplication):
qapplication = True
- def testNoArgs(self):
- '''Connecting a lambda to a signal without arguments'''
- proc = QProcess()
- dummy = Dummy()
- QObject.connect(proc, SIGNAL('started()'),
- lambda: setattr(dummy, 'called', True))
- proc.start(sys.executable, ['-c', '""'])
- proc.waitForFinished()
- self.assertTrue(dummy.called)
-
def testWithArgs(self):
- '''Connecting a lambda to a signal with arguments'''
+ '''Connecting a lambda to a signal with and without arguments'''
proc = QProcess()
- dummy = Dummy()
- QObject.connect(proc, SIGNAL('finished(int)'),
- lambda x: setattr(dummy, 'called', x))
+ dummy = Receiver()
+ proc.started.connect(lambda: setattr(dummy, 'called', True))
+ proc.finished.connect(lambda x: setattr(dummy, 'exit_code', x))
+
proc.start(sys.executable, ['-c', '""'])
- proc.waitForFinished()
- self.assertEqual(dummy.called, proc.exitCode())
+ self.assertTrue(proc.waitForStarted())
+ self.assertTrue(proc.waitForFinished())
+
+ self.assertTrue(dummy.called)
+ self.assertEqual(dummy.exit_code, proc.exitCode())
+
+ def testRelease(self):
+ """PYSIDE-2646: Test whether main thread target slot lambda/methods
+ (and their captured objects) are released by the signal manager
+ after a while."""
+
+ def do_connect(sender):
+ receiver = Receiver()
+ sender.void_signal.connect(lambda: setattr(receiver, 'called', True))
+ return receiver
+
+ sender = Sender()
+ receiver = weakref.ref(do_connect(sender))
+ sender.emit_void()
+ self.assertTrue(receiver().called)
+ del sender
+ for i in range(3):
+ if not receiver():
+ break
+ QCoreApplication.processEvents()
+ self.assertFalse(receiver())
if __name__ == '__main__':
diff --git a/sources/pyside6/tests/signals/leaking_signal_test.py b/sources/pyside6/tests/signals/leaking_signal_test.py
index e7aff9628..666ae7a13 100644
--- a/sources/pyside6/tests/signals/leaking_signal_test.py
+++ b/sources/pyside6/tests/signals/leaking_signal_test.py
@@ -4,7 +4,6 @@
import os
import sys
import unittest
-import weakref
from pathlib import Path
sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
@@ -21,7 +20,7 @@ class LeakingSignal(unittest.TestCase):
class Emitter(QObject):
my_signal = Signal(object)
- emitter = Emitter()
+ emitter = Emitter() # noqa: F841
if __name__ == '__main__':
diff --git a/sources/pyside6/tests/signals/multiple_connections_gui_test.py b/sources/pyside6/tests/signals/multiple_connections_gui_test.py
index 097811750..295369b7d 100644
--- a/sources/pyside6/tests/signals/multiple_connections_gui_test.py
+++ b/sources/pyside6/tests/signals/multiple_connections_gui_test.py
@@ -1,9 +1,7 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-from functools import partial
import os
-import random
import sys
import unittest
@@ -12,22 +10,16 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL
-
-try:
- from PySide6.QtWidgets import QPushButton, QSpinBox
- hasQtGui = True
-except ImportError:
- hasQtGui = False
+from PySide6.QtWidgets import QPushButton, QSpinBox
from helper.basicpyslotcase import BasicPySlotCase
from helper.usesqapplication import UsesQApplication
-class MultipleSignalConnections(unittest.TestCase):
- '''Base class for multiple signal connection testing'''
+class QtGuiMultipleSlots(UsesQApplication):
+ '''Multiple connections to QtGui signals'''
- def run_many(self, sender, signal, emitter, receivers, args=None):
+ def run_many(self, signal, emitter, receivers, args=None):
"""Utility method to connect a list of receivers to a signal.
sender - QObject that will emit the signal
signal - string with the signal signature
@@ -41,7 +33,7 @@ class MultipleSignalConnections(unittest.TestCase):
for rec in receivers:
rec.setUp()
- QObject.connect(sender, SIGNAL(signal), rec.cb)
+ signal.connect(rec.cb)
rec.args = tuple(args)
emitter(*args)
@@ -49,24 +41,20 @@ class MultipleSignalConnections(unittest.TestCase):
for rec in receivers:
self.assertTrue(rec.called)
+ def testButtonClick(self):
+ """Multiple connections to QPushButton.clicked()"""
+ sender = QPushButton('button')
+ receivers = [BasicPySlotCase() for x in range(30)]
+ self.run_many(sender.clicked, sender.click, receivers)
-if hasQtGui:
- class QtGuiMultipleSlots(UsesQApplication, MultipleSignalConnections):
- '''Multiple connections to QtGui signals'''
-
- def testButtonClick(self):
- """Multiple connections to QPushButton.clicked()"""
- sender = QPushButton('button')
- receivers = [BasicPySlotCase() for x in range(30)]
- self.run_many(sender, 'clicked()', sender.click, receivers)
+ def testSpinBoxValueChanged(self):
+ """Multiple connections to QSpinBox.valueChanged(int)"""
+ sender = QSpinBox()
+ # FIXME if number of receivers if higher than 50, segfaults
+ receivers = [BasicPySlotCase() for x in range(10)]
+ self.run_many(sender.valueChanged, sender.setValue,
+ receivers, (1,))
- def testSpinBoxValueChanged(self):
- """Multiple connections to QSpinBox.valueChanged(int)"""
- sender = QSpinBox()
- # FIXME if number of receivers if higher than 50, segfaults
- receivers = [BasicPySlotCase() for x in range(10)]
- self.run_many(sender, 'valueChanged(int)', sender.setValue,
- receivers, (1,))
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside6/tests/signals/multiple_connections_test.py b/sources/pyside6/tests/signals/multiple_connections_test.py
index 783c9414b..233851797 100644
--- a/sources/pyside6/tests/signals/multiple_connections_test.py
+++ b/sources/pyside6/tests/signals/multiple_connections_test.py
@@ -11,16 +11,16 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL, QProcess
+from PySide6.QtCore import QObject, Signal, QProcess
from helper.basicpyslotcase import BasicPySlotCase
-from helper.usesqcoreapplication import UsesQCoreApplication
+from helper.usesqapplication import UsesQApplication
class MultipleSignalConnections(unittest.TestCase):
'''Base class for multiple signal connection testing'''
- def run_many(self, sender, signal, emitter, receivers, args=None):
+ def run_many(self, signal, emitter, receivers, args=None):
"""Utility method to connect a list of receivers to a signal.
sender - QObject that will emit the signal
signal - string with the signal signature
@@ -33,7 +33,7 @@ class MultipleSignalConnections(unittest.TestCase):
args = tuple()
for rec in receivers:
rec.setUp()
- self.assertTrue(QObject.connect(sender, SIGNAL(signal), rec.cb))
+ self.assertTrue(signal.connect(rec.cb))
rec.args = tuple(args)
emitter(*args)
@@ -42,22 +42,23 @@ class MultipleSignalConnections(unittest.TestCase):
self.assertTrue(rec.called)
-class PythonMultipleSlots(UsesQCoreApplication, MultipleSignalConnections):
+class PythonMultipleSlots(UsesQApplication, MultipleSignalConnections):
'''Multiple connections to python signals'''
def testPythonSignal(self):
"""Multiple connections to a python signal (short-circuit)"""
- class Dummy(QObject):
- pass
+ class Sender(QObject):
- sender = Dummy()
+ foobar = Signal(int)
+
+ sender = Sender()
receivers = [BasicPySlotCase() for x in range(10)]
- self.run_many(sender, 'foobar(int)', partial(sender.emit,
- SIGNAL('foobar(int)')), receivers, (0, ))
+ self.run_many(sender.foobar, partial(sender.foobar.emit),
+ receivers, (0, ))
-class QProcessMultipleSlots(UsesQCoreApplication, MultipleSignalConnections):
+class QProcessMultipleSlots(UsesQApplication, MultipleSignalConnections):
'''Multiple connections to QProcess signals'''
def testQProcessStarted(self):
@@ -67,9 +68,10 @@ class QProcessMultipleSlots(UsesQCoreApplication, MultipleSignalConnections):
def start_proc(*args):
sender.start(sys.executable, ['-c', '""'])
- sender.waitForFinished()
+ self.assertTrue(sender.waitForStarted())
+ self.assertTrue(sender.waitForFinished())
- self.run_many(sender, 'started()', start_proc, receivers)
+ self.run_many(sender.started, start_proc, receivers)
def testQProcessFinished(self):
'''Multiple connections to QProcess.finished(int)'''
@@ -78,9 +80,10 @@ class QProcessMultipleSlots(UsesQCoreApplication, MultipleSignalConnections):
def start_proc(*args):
sender.start(sys.executable, ['-c', '""'])
- sender.waitForFinished()
+ self.assertTrue(sender.waitForStarted())
+ self.assertTrue(sender.waitForFinished())
- self.run_many(sender, 'finished(int)', start_proc, receivers, (0,))
+ self.run_many(sender.finished, start_proc, receivers, (0, QProcess.ExitStatus.NormalExit))
if __name__ == '__main__':
diff --git a/sources/pyside6/tests/signals/pysignal_test.py b/sources/pyside6/tests/signals/pysignal_test.py
index e3d6a55da..d6f44edf8 100644
--- a/sources/pyside6/tests/signals/pysignal_test.py
+++ b/sources/pyside6/tests/signals/pysignal_test.py
@@ -11,31 +11,31 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL, SLOT, Qt
-
-try:
- from PySide6.QtWidgets import QSpinBox, QApplication, QWidget
- hasQtGui = True
-except ImportError:
- hasQtGui = False
+from PySide6.QtCore import QObject, Signal, Qt
+from PySide6.QtWidgets import QSpinBox, QApplication, QWidget # noqa: F401
from helper.usesqapplication import UsesQApplication
-class Dummy(QObject):
- """Dummy class used in this test."""
+TEST_LIST = ["item1", "item2", "item3"]
+
+
+class Sender(QObject):
+ """Sender class used in this test."""
+
+ foo = Signal()
+ foo_int = Signal(int)
+ dummy = Signal(str)
+ dummy2 = Signal(str, list)
+
def __init__(self, parent=None):
- QObject.__init__(self, parent)
+ super().__init__(parent)
def callDummy(self):
- self.emit(SIGNAL("dummy(PyObject)"), "PyObject")
+ self.dummy.emit("PyObject")
def callDummy2(self):
- lst = []
- lst.append("item1")
- lst.append("item2")
- lst.append("item3")
- self.emit(SIGNAL("dummy2(PyObject, PyObject)"), "PyObject0", lst)
+ self.dummy2.emit("PyObject0", TEST_LIST)
class PyObjectType(UsesQApplication):
@@ -46,35 +46,33 @@ class PyObjectType(UsesQApplication):
def mySlot2(self, arg0, arg1):
self.assertEqual(arg0, "PyObject0")
- self.assertEqual(arg1[0], "item1")
- self.assertEqual(arg1[1], "item2")
- self.assertEqual(arg1[2], "item3")
+ self.assertEqual(arg1, TEST_LIST)
self.callCount += 1
if self.running:
self.app.quit()
def setUp(self):
- super(PyObjectType, self).setUp()
+ super().setUp()
self.callCount = 0
self.running = False
def testWithOneArg(self):
- o = Dummy()
- o.connect(SIGNAL("dummy(PyObject)"), self.mySlot)
+ o = Sender()
+ o.dummy.connect(self.mySlot)
o.callDummy()
self.assertEqual(self.callCount, 1)
def testWithTwoArg(self):
- o = Dummy()
- o.connect(SIGNAL("dummy2(PyObject,PyObject)"), self.mySlot2)
+ o = Sender()
+ o.dummy2.connect(self.mySlot2)
o.callDummy2()
self.assertEqual(self.callCount, 1)
def testAsyncSignal(self):
self.called = False
self.running = True
- o = Dummy()
- o.connect(SIGNAL("dummy2(PyObject,PyObject)"), self.mySlot2, Qt.QueuedConnection)
+ o = Sender()
+ o.dummy2.connect(self.mySlot2, Qt.QueuedConnection)
o.callDummy2()
self.app.exec()
self.assertEqual(self.callCount, 1)
@@ -82,8 +80,8 @@ class PyObjectType(UsesQApplication):
def testTwice(self):
self.called = False
self.running = True
- o = Dummy()
- o.connect(SIGNAL("dummy2(PyObject,PyObject)"), self.mySlot2, Qt.QueuedConnection)
+ o = Sender()
+ o.dummy2.connect(self.mySlot2, Qt.QueuedConnection)
o.callDummy2()
o.callDummy2()
self.app.exec()
@@ -97,7 +95,7 @@ class PythonSigSlot(unittest.TestCase):
def tearDown(self):
try:
del self.args
- except:
+ except: # noqa: E722
pass
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
@@ -108,98 +106,98 @@ class PythonSigSlot(unittest.TestCase):
def testNoArgs(self):
"""Python signal and slots without arguments"""
- obj1 = Dummy()
+ obj1 = Sender()
- QObject.connect(obj1, SIGNAL('foo()'), self.callback)
+ obj1.foo.connect(self.callback)
self.args = tuple()
- obj1.emit(SIGNAL('foo()'), *self.args)
+ obj1.foo.emit(*self.args)
self.assertTrue(self.called)
def testWithArgs(self):
"""Python signal and slots with integer arguments"""
- obj1 = Dummy()
+ obj1 = Sender()
- QObject.connect(obj1, SIGNAL('foo(int)'), self.callback)
+ obj1.foo_int.connect(self.callback)
self.args = (42,)
- obj1.emit(SIGNAL('foo(int)'), *self.args)
+ obj1.foo_int.emit(*self.args)
self.assertTrue(self.called)
def testDisconnect(self):
- obj1 = Dummy()
+ obj1 = Sender()
- QObject.connect(obj1, SIGNAL('foo(int)'), self.callback)
- QObject.disconnect(obj1, SIGNAL('foo(int)'), self.callback)
+ obj1.foo_int.connect(self.callback)
+ self.assertTrue(obj1.foo_int.disconnect(self.callback))
self.args = (42, )
- obj1.emit(SIGNAL('foo(int)'), *self.args)
+ obj1.foo_int.emit(*self.args)
self.assertTrue(not self.called)
-if hasQtGui:
- class SpinBoxPySignal(UsesQApplication):
- """Tests the connection of python signals to QSpinBox qt slots."""
+class SpinBoxPySignal(UsesQApplication):
+ """Tests the connection of python signals to QSpinBox qt slots."""
- def setUp(self):
- super(SpinBoxPySignal, self).setUp()
- self.obj = Dummy()
- self.spin = QSpinBox()
- self.spin.setValue(0)
+ def setUp(self):
+ super().setUp()
+ self.obj = Sender()
+ self.spin = QSpinBox()
+ self.spin.setValue(0)
- def tearDown(self):
- super(SpinBoxPySignal, self).tearDown()
- del self.obj
- del self.spin
- # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
- gc.collect()
+ def tearDown(self):
+ super().tearDown()
+ del self.obj
+ del self.spin
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testValueChanged(self):
+ """Emission of a python signal to QSpinBox setValue(int)"""
- def testValueChanged(self):
- """Emission of a python signal to QSpinBox setValue(int)"""
- QObject.connect(self.obj, SIGNAL('dummy(int)'), self.spin, SLOT('setValue(int)'))
- self.assertEqual(self.spin.value(), 0)
+ self.obj.foo_int.connect(self.spin.setValue)
+ self.assertEqual(self.spin.value(), 0)
- self.obj.emit(SIGNAL('dummy(int)'), 4)
- self.assertEqual(self.spin.value(), 4)
+ self.obj.foo_int.emit(4)
+ self.assertEqual(self.spin.value(), 4)
- def testValueChangedMultiple(self):
- """Multiple emissions of a python signal to QSpinBox setValue(int)"""
- QObject.connect(self.obj, SIGNAL('dummy(int)'), self.spin, SLOT('setValue(int)'))
- self.assertEqual(self.spin.value(), 0)
+ def testValueChangedMultiple(self):
+ """Multiple emissions of a python signal to QSpinBox setValue(int)"""
+ self.obj.foo_int.connect(self.spin.setValue)
+ self.assertEqual(self.spin.value(), 0)
- self.obj.emit(SIGNAL('dummy(int)'), 4)
- self.assertEqual(self.spin.value(), 4)
+ self.obj.foo_int.emit(4)
+ self.assertEqual(self.spin.value(), 4)
- self.obj.emit(SIGNAL('dummy(int)'), 77)
- self.assertEqual(self.spin.value(), 77)
+ self.obj.foo_int.emit(77)
+ self.assertEqual(self.spin.value(), 77)
-if hasQtGui:
- class WidgetPySignal(UsesQApplication):
- """Tests the connection of python signals to QWidget qt slots."""
+class WidgetPySignal(UsesQApplication):
+ """Tests the connection of python signals to QWidget qt slots."""
+
+ def setUp(self):
+ super(WidgetPySignal, self).setUp()
+ self.obj = Sender()
+ self.widget = QWidget()
- def setUp(self):
- super(WidgetPySignal, self).setUp()
- self.obj = Dummy()
- self.widget = QWidget()
+ def tearDown(self):
+ super(WidgetPySignal, self).tearDown()
+ del self.obj
+ del self.widget
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
- def tearDown(self):
- super(WidgetPySignal, self).tearDown()
- del self.obj
- del self.widget
- # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
- gc.collect()
+ def testShow(self):
+ """Emission of a python signal to QWidget slot show()"""
+ self.widget.hide()
- def testShow(self):
- """Emission of a python signal to QWidget slot show()"""
- self.widget.hide()
+ self.obj.foo.connect(self.widget.show)
+ self.assertTrue(not self.widget.isVisible())
- QObject.connect(self.obj, SIGNAL('dummy()'), self.widget, SLOT('show()'))
- self.assertTrue(not self.widget.isVisible())
+ self.obj.foo.emit()
+ self.assertTrue(self.widget.isVisible())
- self.obj.emit(SIGNAL('dummy()'))
- self.assertTrue(self.widget.isVisible())
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside6/tests/signals/qobject_callable_connect_test.py b/sources/pyside6/tests/signals/qobject_callable_connect_test.py
new file mode 100644
index 000000000..a7a26d6f5
--- /dev/null
+++ b/sources/pyside6/tests/signals/qobject_callable_connect_test.py
@@ -0,0 +1,45 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+class Emitter(QObject):
+ sig = Signal(int)
+
+
+class CallableObject(QObject):
+ called = False
+ x = 0
+
+ def __call__(self, x: int):
+ self.called = True
+ self.x = x
+
+
+class QObjectCallableConnectTest(unittest.TestCase):
+ '''Test case for QObject.connect() when the callable is also a QObject.'''
+
+ def testCallableConnect(self):
+ emitter = Emitter()
+ obj = CallableObject()
+ x = 1
+
+ emitter.sig.connect(obj)
+ emitter.sig.emit(x)
+
+ self.assertTrue(obj.called)
+ self.assertEqual(obj.x, x)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/qobject_destroyed_test.py b/sources/pyside6/tests/signals/qobject_destroyed_test.py
index 08807e78e..a21762b41 100644
--- a/sources/pyside6/tests/signals/qobject_destroyed_test.py
+++ b/sources/pyside6/tests/signals/qobject_destroyed_test.py
@@ -11,7 +11,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL
+from PySide6.QtCore import QObject
class QObjectDestroyed(unittest.TestCase):
diff --git a/sources/pyside6/tests/signals/qobject_sender_test.py b/sources/pyside6/tests/signals/qobject_sender_test.py
index 1f01b57e5..9c1121eb8 100644
--- a/sources/pyside6/tests/signals/qobject_sender_test.py
+++ b/sources/pyside6/tests/signals/qobject_sender_test.py
@@ -13,8 +13,8 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QCoreApplication, QObject, QTimer, SIGNAL
-from helper.usesqcoreapplication import UsesQCoreApplication
+from PySide6.QtCore import QCoreApplication, QObject, QTimer, Signal
+from helper.usesqapplication import UsesQApplication
class ExtQTimer(QTimer):
@@ -22,6 +22,10 @@ class ExtQTimer(QTimer):
super().__init__()
+class Sender(QObject):
+ foo = Signal()
+
+
class Receiver(QObject):
def __init__(self):
super().__init__()
@@ -37,10 +41,10 @@ class ObjectSenderTest(unittest.TestCase):
'''Test case for QObject.sender() method.'''
def testSenderPythonSignal(self):
- sender = QObject()
+ sender = Sender()
recv = Receiver()
- QObject.connect(sender, SIGNAL('foo()'), recv.callback)
- sender.emit(SIGNAL('foo()'))
+ sender.foo.connect(recv.callback)
+ sender.foo.emit()
self.assertEqual(sender, recv.the_sender)
@@ -48,14 +52,14 @@ class ObjectSenderCheckOnReceiverTest(unittest.TestCase):
'''Test case for QObject.sender() method, this one tests the equality on the Receiver object.'''
def testSenderPythonSignal(self):
- sender = QObject()
+ sender = Sender()
recv = Receiver()
- QObject.connect(sender, SIGNAL('foo()'), recv.callback)
- sender.emit(SIGNAL('foo()'))
+ sender.foo.connect(recv.callback)
+ sender.foo.emit()
self.assertEqual(sender, recv.the_sender)
-class ObjectSenderWithQAppTest(UsesQCoreApplication):
+class ObjectSenderWithQAppTest(UsesQApplication):
'''Test case for QObject.sender() method with QApplication.'''
def testSenderCppSignal(self):
@@ -73,6 +77,12 @@ class ObjectSenderWithQAppTest(UsesQCoreApplication):
self.app.exec()
self.assertTrue(isinstance(recv.the_sender, QObject))
+ def testSenderCppSignalSingleShotTimerWithContext(self):
+ recv = Receiver()
+ QTimer.singleShot(10, recv, recv.callback)
+ self.app.exec()
+ self.assertTrue(isinstance(recv.the_sender, QObject))
+
def testSenderCppSignalWithPythonExtendedClass(self):
sender = ExtQTimer()
recv = Receiver()
@@ -82,7 +92,7 @@ class ObjectSenderWithQAppTest(UsesQCoreApplication):
self.assertEqual(sender, recv.the_sender)
-class ObjectSenderWithQAppCheckOnReceiverTest(UsesQCoreApplication):
+class ObjectSenderWithQAppCheckOnReceiverTest(UsesQApplication):
'''Test case for QObject.sender() method with QApplication.'''
def testSenderCppSignal(self):
@@ -105,4 +115,3 @@ class ObjectSenderWithQAppCheckOnReceiverTest(UsesQCoreApplication):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/ref01_test.py b/sources/pyside6/tests/signals/ref01_test.py
index a830b55dd..1a62b2218 100644
--- a/sources/pyside6/tests/signals/ref01_test.py
+++ b/sources/pyside6/tests/signals/ref01_test.py
@@ -37,5 +37,3 @@ class BoundAndUnboundSignalsTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
-
diff --git a/sources/pyside6/tests/signals/ref02_test.py b/sources/pyside6/tests/signals/ref02_test.py
index db456b35b..54b6f4a52 100644
--- a/sources/pyside6/tests/signals/ref02_test.py
+++ b/sources/pyside6/tests/signals/ref02_test.py
@@ -12,14 +12,14 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QCoreApplication, QTimeLine
-from helper.usesqcoreapplication import UsesQCoreApplication
+from PySide6.QtCore import QTimeLine
+from helper.usesqapplication import UsesQApplication
-class NativeSignalsTest(UsesQCoreApplication):
+class NativeSignalsTest(UsesQApplication):
def setUp(self):
- UsesQCoreApplication.setUp(self)
+ UsesQApplication.setUp(self)
self.called = False
self.timeline = QTimeLine(100)
@@ -28,7 +28,7 @@ class NativeSignalsTest(UsesQCoreApplication):
del self.timeline
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
- UsesQCoreApplication.tearDown(self)
+ UsesQApplication.tearDown(self)
def testSignalWithIntArgument(self):
@@ -58,4 +58,3 @@ class NativeSignalsTest(UsesQCoreApplication):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/ref03_test.py b/sources/pyside6/tests/signals/ref03_test.py
index 2df2d7cef..c43c2e549 100644
--- a/sources/pyside6/tests/signals/ref03_test.py
+++ b/sources/pyside6/tests/signals/ref03_test.py
@@ -40,4 +40,3 @@ class DisconnectSignalsTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/ref04_test.py b/sources/pyside6/tests/signals/ref04_test.py
index b478aff2a..fce801456 100644
--- a/sources/pyside6/tests/signals/ref04_test.py
+++ b/sources/pyside6/tests/signals/ref04_test.py
@@ -53,17 +53,6 @@ class UserSignalTest(unittest.TestCase):
self.emitter.mySignal.emit()
self.assertEqual(self.counter, 2)
-# def testConnectWithConfigureMethod(self):
-#
-# def slot():
-# self.counter += 1
-#
-# self.emitter.pyqtConfigure(mySignal=slot)
-# self.assertEqual(self.counter, 0)
-# self.emitter.mySignal.emit()
-# self.assertEqual(self.counter, 1)
-
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/ref05_test.py b/sources/pyside6/tests/signals/ref05_test.py
index 13ab1ff65..fb9debf39 100644
--- a/sources/pyside6/tests/signals/ref05_test.py
+++ b/sources/pyside6/tests/signals/ref05_test.py
@@ -12,8 +12,8 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, QCoreApplication, QTimeLine, Slot
-from helper.usesqcoreapplication import UsesQCoreApplication
+from PySide6.QtCore import QObject, QTimeLine, Slot
+from helper.usesqapplication import UsesQApplication
class ExtQObject(QObject):
@@ -27,10 +27,10 @@ class ExtQObject(QObject):
self.counter += 1
-class UserSlotTest(UsesQCoreApplication):
+class UserSlotTest(UsesQApplication):
def setUp(self):
- UsesQCoreApplication.setUp(self)
+ UsesQApplication.setUp(self)
self.receiver = ExtQObject()
self.timeline = QTimeLine(100)
@@ -39,7 +39,7 @@ class UserSlotTest(UsesQCoreApplication):
del self.receiver
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
- UsesQCoreApplication.tearDown(self)
+ UsesQApplication.tearDown(self)
def testUserSlot(self):
self.timeline.setUpdateInterval(10)
@@ -56,4 +56,3 @@ class UserSlotTest(UsesQCoreApplication):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/ref06_test.py b/sources/pyside6/tests/signals/ref06_test.py
index 56d54c1af..a827131db 100644
--- a/sources/pyside6/tests/signals/ref06_test.py
+++ b/sources/pyside6/tests/signals/ref06_test.py
@@ -12,8 +12,8 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, QCoreApplication, QTimeLine, Signal, Slot
-from helper.usesqcoreapplication import UsesQCoreApplication
+from PySide6.QtCore import QObject, QTimeLine, Signal, Slot
+from helper.usesqapplication import UsesQApplication
class ExtQObject(QObject):
@@ -28,10 +28,10 @@ class ExtQObject(QObject):
self.counter += 1
-class SignaltoSignalTest(UsesQCoreApplication):
+class SignaltoSignalTest(UsesQApplication):
def setUp(self):
- UsesQCoreApplication.setUp(self)
+ UsesQApplication.setUp(self)
self.receiver = ExtQObject()
self.timeline = QTimeLine(100)
@@ -40,7 +40,7 @@ class SignaltoSignalTest(UsesQCoreApplication):
del self.receiver
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
- UsesQCoreApplication.tearDown(self)
+ UsesQApplication.tearDown(self)
def testSignaltoSignal(self):
self.timeline.setUpdateInterval(10)
@@ -59,4 +59,3 @@ class SignaltoSignalTest(UsesQCoreApplication):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/segfault_proxyparent_test.py b/sources/pyside6/tests/signals/segfault_proxyparent_test.py
index c85ab10c0..cb0df0978 100644
--- a/sources/pyside6/tests/signals/segfault_proxyparent_test.py
+++ b/sources/pyside6/tests/signals/segfault_proxyparent_test.py
@@ -11,7 +11,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL
+from PySide6.QtCore import QObject, Signal
# Description of the problem
# After creating an PyObject that inherits from QObject, connecting it,
@@ -20,16 +20,19 @@ from PySide6.QtCore import QObject, SIGNAL
# Somehow the underlying QObject also points to the same position.
-# In PyQt4, the connection works fine with the same memory behavior,
-# so it looks like specific to SIP.
+class Sender(QObject):
+
+ bar = Signal(int)
-class Dummy(QObject):
def __init__(self, parent=None):
QObject.__init__(self, parent)
class Joe(QObject):
+
+ bar = Signal(int)
+
def __init__(self, parent=None):
QObject.__init__(self, parent)
@@ -44,7 +47,7 @@ class SegfaultCase(unittest.TestCase):
def tearDown(self):
try:
del self.args
- except:
+ except: # noqa: E722
pass
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
@@ -55,22 +58,21 @@ class SegfaultCase(unittest.TestCase):
def testSegfault(self):
"""Regression: Segfault for qobjects in the same memory position."""
- obj = Dummy()
- QObject.connect(obj, SIGNAL('bar(int)'), self.callback)
+ obj = Sender()
+ obj.bar.connect(self.callback)
self.args = (33,)
- obj.emit(SIGNAL('bar(int)'), self.args[0])
+ obj.bar.emit(self.args[0])
self.assertTrue(self.called)
del obj
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
obj = Joe()
- QObject.connect(obj, SIGNAL('bar(int)'), self.callback)
+ obj.bar.connect(self.callback)
self.args = (33,)
- obj.emit(SIGNAL('bar(int)'), self.args[0])
+ obj.bar.emit(self.args[0])
self.assertTrue(self.called)
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/self_connect_test.py b/sources/pyside6/tests/signals/self_connect_test.py
index d6c03db18..08ca725f8 100644
--- a/sources/pyside6/tests/signals/self_connect_test.py
+++ b/sources/pyside6/tests/signals/self_connect_test.py
@@ -13,17 +13,27 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL, SLOT
+from PySide6.QtCore import QObject, Slot
from PySide6.QtWidgets import QPushButton, QWidget
from helper.usesqapplication import UsesQApplication
+class Receiver(QObject):
+ def __init__(self, p=None):
+ super().__init__(p)
+ self.triggered = False
+
+ @Slot(bool, int)
+ def default_parameter_slot(self, bool_value, int_value=0):
+ self.triggered = True
+
+
class SelfConnect(UsesQApplication):
def testButtonClickClose(self):
button = QPushButton()
- button.connect(button, SIGNAL('clicked()'), SLOT('close()'))
+ button.clicked.connect(button.close)
button.show()
self.assertTrue(button.isVisible())
@@ -33,13 +43,22 @@ class SelfConnect(UsesQApplication):
def testWindowButtonClickClose(self):
button = QPushButton()
window = QWidget()
- window.connect(button, SIGNAL('clicked()'), SLOT('close()'))
+ button.clicked.connect(window.close)
window.show()
self.assertTrue(window.isVisible())
button.click()
self.assertTrue(not window.isVisible())
+ def testDefaultParameters(self):
+ button = QPushButton()
+ receiver = Receiver(button)
+ button.clicked.connect(receiver.default_parameter_slot)
+ button.clicked.connect(button.close)
+ button.show()
+ button.click()
+ self.assertTrue(receiver.triggered)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside6/tests/signals/short_circuit_test.py b/sources/pyside6/tests/signals/short_circuit_test.py
index 434518336..1ad4bc24c 100644
--- a/sources/pyside6/tests/signals/short_circuit_test.py
+++ b/sources/pyside6/tests/signals/short_circuit_test.py
@@ -11,11 +11,17 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL, SLOT
+from PySide6.QtCore import QObject, Signal
-class Dummy(QObject):
- """Dummy class used in this test."""
+class Sender(QObject):
+ """Sender class used in this test."""
+
+ foo = Signal()
+ foo_int = Signal(int)
+ foo_int_int_string = Signal(int, int, str)
+ foo_int_qobject = Signal(int, QObject)
+
def __init__(self, parent=None):
QObject.__init__(self, parent)
@@ -27,7 +33,7 @@ class ShortCircuitSignals(unittest.TestCase):
def tearDown(self):
try:
del self.args
- except:
+ except: # noqa: E722
pass
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
@@ -38,40 +44,40 @@ class ShortCircuitSignals(unittest.TestCase):
def testNoArgs(self):
"""Short circuit signal without arguments"""
- obj1 = Dummy()
- QObject.connect(obj1, SIGNAL('foo()'), self.callback)
+ obj1 = Sender()
+ obj1.foo.connect(self.callback)
self.args = tuple()
- obj1.emit(SIGNAL('foo()'), *self.args)
+ obj1.foo.emit(*self.args)
self.assertTrue(self.called)
def testWithArgs(self):
"""Short circuit signal with integer arguments"""
- obj1 = Dummy()
+ obj1 = Sender()
- QObject.connect(obj1, SIGNAL('foo(int)'), self.callback)
+ obj1.foo_int.connect(self.callback)
self.args = (42,)
- obj1.emit(SIGNAL('foo(int)'), *self.args)
+ obj1.foo_int.emit(*self.args)
self.assertTrue(self.called)
def testMultipleArgs(self):
"""Short circuit signal with multiple arguments"""
- obj1 = Dummy()
+ obj1 = Sender()
- QObject.connect(obj1, SIGNAL('foo(int,int,QString)'), self.callback)
+ obj1.foo_int_int_string.connect(self.callback)
self.args = (42, 33, 'char')
- obj1.emit(SIGNAL('foo(int,int,QString)'), *self.args)
+ obj1.foo_int_int_string.emit(*self.args)
self.assertTrue(self.called)
def testComplexArgs(self):
"""Short circuit signal with complex arguments"""
- obj1 = Dummy()
+ obj1 = Sender()
- QObject.connect(obj1, SIGNAL('foo(int,QObject*)'), self.callback)
+ obj1.foo_int_qobject.connect(self.callback)
self.args = (42, obj1)
- obj1.emit(SIGNAL('foo(int,QObject*)'), *self.args)
+ obj1.foo_int_qobject.emit(*self.args)
self.assertTrue(self.called)
diff --git a/sources/pyside6/tests/signals/signal2signal_connect_test.py b/sources/pyside6/tests/signals/signal2signal_connect_test.py
index c755a9dca..31129f7a1 100644
--- a/sources/pyside6/tests/signals/signal2signal_connect_test.py
+++ b/sources/pyside6/tests/signals/signal2signal_connect_test.py
@@ -13,7 +13,20 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL
+from PySide6.QtCore import QObject, Signal
+
+
+class Sender(QObject):
+
+ mysignal_int = Signal(int)
+ mysignal_int_int = Signal(int, int)
+ mysignal_string = Signal(str)
+
+
+class Forwarder(Sender):
+
+ forward = Signal()
+ forward_qobject = Signal(QObject)
def cute_slot():
@@ -25,8 +38,8 @@ class TestSignal2SignalConnect(unittest.TestCase):
def setUp(self):
# Set up the basic resources needed
- self.sender = QObject()
- self.forwarder = QObject()
+ self.sender = Sender()
+ self.forwarder = Forwarder()
self.args = None
self.called = False
@@ -34,11 +47,11 @@ class TestSignal2SignalConnect(unittest.TestCase):
# Delete used resources
try:
del self.sender
- except:
+ except: # noqa: E722
pass
try:
del self.forwarder
- except:
+ except: # noqa: E722
pass
del self.args
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
@@ -63,47 +76,37 @@ class TestSignal2SignalConnect(unittest.TestCase):
raise TypeError("Invalid arguments")
def testSignalWithoutArguments(self):
- QObject.connect(self.sender, SIGNAL("destroyed()"),
- self.forwarder, SIGNAL("forward()"))
- QObject.connect(self.forwarder, SIGNAL("forward()"),
- self.callback_noargs)
+ self.sender.destroyed.connect(self.forwarder.forward)
+ self.forwarder.forward.connect(self.callback_noargs)
del self.sender
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
self.assertTrue(self.called)
def testSignalWithOnePrimitiveTypeArgument(self):
- QObject.connect(self.sender, SIGNAL("mysignal(int)"),
- self.forwarder, SIGNAL("mysignal(int)"))
- QObject.connect(self.forwarder, SIGNAL("mysignal(int)"),
- self.callback_args)
+ self.sender.mysignal_int.connect(self.forwarder.mysignal_int)
+ self.forwarder.mysignal_int.connect(self.callback_args)
self.args = (19,)
- self.sender.emit(SIGNAL('mysignal(int)'), *self.args)
+ self.sender.mysignal_int.emit(*self.args)
self.assertTrue(self.called)
def testSignalWithMultiplePrimitiveTypeArguments(self):
- QObject.connect(self.sender, SIGNAL("mysignal(int,int)"),
- self.forwarder, SIGNAL("mysignal(int,int)"))
- QObject.connect(self.forwarder, SIGNAL("mysignal(int,int)"),
- self.callback_args)
+ self.sender.mysignal_int_int.connect(self.forwarder.mysignal_int_int)
+ self.forwarder.mysignal_int_int.connect(self.callback_args)
self.args = (23, 29)
- self.sender.emit(SIGNAL('mysignal(int,int)'), *self.args)
+ self.sender.mysignal_int_int.emit(*self.args)
self.assertTrue(self.called)
def testSignalWithOneStringArgument(self):
- QObject.connect(self.sender, SIGNAL("mysignal(QString)"),
- self.forwarder, SIGNAL("mysignal(QString)"))
- QObject.connect(self.forwarder, SIGNAL("mysignal(QString)"),
- self.callback_args)
+ self.sender.mysignal_string.connect(self.forwarder.mysignal_string)
+ self.forwarder.mysignal_string.connect(self.callback_args)
self.args = ('myargument',)
- self.sender.emit(SIGNAL('mysignal(QString)'), *self.args)
+ self.sender.mysignal_string.emit(*self.args)
self.assertTrue(self.called)
def testSignalWithOneQObjectArgument(self):
- QObject.connect(self.sender, SIGNAL('destroyed(QObject*)'),
- self.forwarder, SIGNAL('forward(QObject*)'))
- QObject.connect(self.forwarder, SIGNAL('forward(QObject*)'),
- self.callback_qobject)
+ self.sender.destroyed.connect(self.forwarder.forward_qobject)
+ self.forwarder.forward_qobject.connect(self.callback_qobject)
obj_name = 'sender'
self.sender.setObjectName(obj_name)
@@ -116,5 +119,3 @@ class TestSignal2SignalConnect(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
-
diff --git a/sources/pyside6/tests/signals/signal_across_threads.py b/sources/pyside6/tests/signals/signal_across_threads.py
index ad4b806ed..91b1ca986 100644
--- a/sources/pyside6/tests/signals/signal_across_threads.py
+++ b/sources/pyside6/tests/signals/signal_across_threads.py
@@ -14,7 +14,7 @@ from init_paths import init_test_paths
init_test_paths(False)
from PySide6.QtCore import QObject, QThread, QTimer, Slot
-from helper.usesqcoreapplication import UsesQCoreApplication
+from helper.usesqapplication import UsesQApplication
class ReceiverBase(QObject):
@@ -39,9 +39,9 @@ class TestThread(QThread):
pass
-class SignalAcrossThreads(UsesQCoreApplication):
+class SignalAcrossThreads(UsesQApplication):
def setUp(self):
- UsesQCoreApplication.setUp(self)
+ UsesQApplication.setUp(self)
self._timer_tick = 0
self._timer = QTimer()
self._timer.setInterval(20)
@@ -49,7 +49,7 @@ class SignalAcrossThreads(UsesQCoreApplication):
self._worker_thread = TestThread()
def tearDown(self):
- UsesQCoreApplication.tearDown(self)
+ UsesQApplication.tearDown(self)
@Slot()
def _control_test(self):
diff --git a/sources/pyside6/tests/signals/signal_autoconnect_test.py b/sources/pyside6/tests/signals/signal_autoconnect_test.py
index 820a77444..51d1cea3a 100644
--- a/sources/pyside6/tests/signals/signal_autoconnect_test.py
+++ b/sources/pyside6/tests/signals/signal_autoconnect_test.py
@@ -27,7 +27,7 @@ class MyObject(QWidget):
class AutoConnectionTest(unittest.TestCase):
def testConnection(self):
- app = QApplication([])
+ app = QApplication([]) # noqa: F841
win = MyObject()
btn = QPushButton("click", win)
diff --git a/sources/pyside6/tests/signals/signal_connectiontype_support_test.py b/sources/pyside6/tests/signals/signal_connectiontype_support_test.py
index 95ce1fa4f..0a69c1e02 100644
--- a/sources/pyside6/tests/signals/signal_connectiontype_support_test.py
+++ b/sources/pyside6/tests/signals/signal_connectiontype_support_test.py
@@ -10,13 +10,16 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL, Qt
+from PySide6.QtCore import QObject, Signal, Qt
-class Dummy(QObject):
+class Sender(QObject):
"""Dummy class used in this test."""
+
+ foo = Signal()
+
def __init__(self, parent=None):
- QObject.__init__(self, parent)
+ super().__init__(parent)
class TestConnectionTypeSupport(unittest.TestCase):
@@ -26,11 +29,11 @@ class TestConnectionTypeSupport(unittest.TestCase):
def testNoArgs(self):
"""Connect signal using a Qt.ConnectionType as argument"""
- obj1 = Dummy()
+ obj1 = Sender()
- QObject.connect(obj1, SIGNAL('foo()'), self.callback, Qt.DirectConnection)
+ obj1.foo.connect(self.callback, Qt.DirectConnection)
self.args = tuple()
- obj1.emit(SIGNAL('foo()'), *self.args)
+ obj1.foo.emit(*self.args)
self.assertTrue(self.called)
diff --git a/sources/pyside6/tests/signals/signal_emission_gui_test.py b/sources/pyside6/tests/signals/signal_emission_gui_test.py
index aae96f236..5a49b9d12 100644
--- a/sources/pyside6/tests/signals/signal_emission_gui_test.py
+++ b/sources/pyside6/tests/signals/signal_emission_gui_test.py
@@ -14,112 +14,104 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL, SLOT
-
-try:
- from PySide6.QtWidgets import QSpinBox, QPushButton
- hasQtGui = True
-except ImportError:
- hasQtGui = False
+from PySide6.QtWidgets import QSpinBox, QPushButton
from helper.basicpyslotcase import BasicPySlotCase
from helper.usesqapplication import UsesQApplication
-if hasQtGui:
- class ButtonPySlot(UsesQApplication, BasicPySlotCase):
- """Tests the connection of python slots to QPushButton signals"""
-
- def testButtonClicked(self):
- """Connection of a python slot to QPushButton.clicked()"""
- button = QPushButton('Mylabel')
- button.clicked.connect(self.cb)
- self.args = tuple()
- button.emit(SIGNAL('clicked(bool)'), False)
- self.assertTrue(self.called)
-
- def testButtonClick(self):
- """Indirect qt signal emission using the QPushButton.click() method """
- button = QPushButton('label')
- button.clicked.connect(self.cb)
- self.args = tuple()
- button.click()
- self.assertTrue(self.called)
-
-
-if hasQtGui:
- class SpinBoxPySlot(UsesQApplication, BasicPySlotCase):
- """Tests the connection of python slots to QSpinBox signals"""
-
- def setUp(self):
- super(SpinBoxPySlot, self).setUp()
- self.spin = QSpinBox()
-
- def tearDown(self):
- del self.spin
- # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
- gc.collect()
- super(SpinBoxPySlot, self).tearDown()
-
- def testSpinBoxValueChanged(self):
- """Connection of a python slot to QSpinBox.valueChanged(int)"""
- self.spin.valueChanged.connect(self.cb)
- self.args = [3]
- self.spin.emit(SIGNAL('valueChanged(int)'), *self.args)
- self.assertTrue(self.called)
-
- def testSpinBoxValueChangedImplicit(self):
- """Indirect qt signal emission using QSpinBox.setValue(int)"""
- self.spin.valueChanged.connect(self.cb)
- self.args = [42]
- self.spin.setValue(self.args[0])
- self.assertTrue(self.called)
-
- def atestSpinBoxValueChangedFewArgs(self):
- """Emission of signals with fewer arguments than needed"""
- # XXX: PyQt4 crashes on the assertRaises
- self.spin.valueChanged.connect(self.cb)
- self.args = (554,)
- self.assertRaises(TypeError, self.spin.emit, SIGNAL('valueChanged(int)'))
-
-if hasQtGui:
- class QSpinBoxQtSlots(UsesQApplication):
- """Tests the connection to QSpinBox qt slots"""
-
- qapplication = True
-
- def testSetValueIndirect(self):
- """Indirect signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
- spinSend = QSpinBox()
- spinRec = QSpinBox()
-
- spinRec.setValue(5)
-
- spinSend.valueChanged.connect(spinRec.setValue)
- self.assertEqual(spinRec.value(), 5)
- spinSend.setValue(3)
- self.assertEqual(spinRec.value(), 3)
- self.assertEqual(spinSend.value(), 3)
-
- def testSetValue(self):
- """Direct signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
- spinSend = QSpinBox()
- spinRec = QSpinBox()
-
- spinRec.setValue(5)
- spinSend.setValue(42)
-
- spinSend.valueChanged.connect(spinRec.setValue)
- self.assertEqual(spinRec.value(), 5)
- self.assertEqual(spinSend.value(), 42)
- spinSend.emit(SIGNAL('valueChanged(int)'), 3)
-
- self.assertEqual(spinRec.value(), 3)
- # Direct emission shouldn't change the value of the emitter
- self.assertEqual(spinSend.value(), 42)
-
- spinSend.emit(SIGNAL('valueChanged(int)'), 66)
- self.assertEqual(spinRec.value(), 66)
- self.assertEqual(spinSend.value(), 42)
+
+class ButtonPySlot(UsesQApplication, BasicPySlotCase):
+ """Tests the connection of python slots to QPushButton signals"""
+
+ def testButtonClicked(self):
+ """Connection of a python slot to QPushButton.clicked()"""
+ button = QPushButton('Mylabel')
+ button.clicked.connect(self.cb)
+ self.args = tuple()
+ button.clicked.emit()
+ self.assertTrue(self.called)
+
+ def testButtonClick(self):
+ """Indirect qt signal emission using the QPushButton.click() method """
+ button = QPushButton('label')
+ button.clicked.connect(self.cb)
+ self.args = tuple()
+ button.click()
+ self.assertTrue(self.called)
+
+
+class SpinBoxPySlot(UsesQApplication, BasicPySlotCase):
+ """Tests the connection of python slots to QSpinBox signals"""
+
+ def setUp(self):
+ super(SpinBoxPySlot, self).setUp()
+ self.spin = QSpinBox()
+
+ def tearDown(self):
+ del self.spin
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(SpinBoxPySlot, self).tearDown()
+
+ def testSpinBoxValueChanged(self):
+ """Connection of a python slot to QSpinBox.valueChanged(int)"""
+ self.spin.valueChanged.connect(self.cb)
+ self.args = [3]
+ self.spin.valueChanged.emit(*self.args)
+ self.assertTrue(self.called)
+
+ def testSpinBoxValueChangedImplicit(self):
+ """Indirect qt signal emission using QSpinBox.setValue(int)"""
+ self.spin.valueChanged.connect(self.cb)
+ self.args = [42]
+ self.spin.setValue(self.args[0])
+ self.assertTrue(self.called)
+
+ def atestSpinBoxValueChangedFewArgs(self):
+ """Emission of signals with fewer arguments than needed"""
+ self.spin.valueChanged.connect(self.cb)
+ self.args = (554,)
+ self.assertRaises(TypeError, self.spin.valueChanged.emit)
+
+
+class QSpinBoxQtSlots(UsesQApplication):
+ """Tests the connection to QSpinBox qt slots"""
+
+ qapplication = True
+
+ def testSetValueIndirect(self):
+ """Indirect signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
+ spinSend = QSpinBox()
+ spinRec = QSpinBox()
+
+ spinRec.setValue(5)
+
+ spinSend.valueChanged.connect(spinRec.setValue)
+ self.assertEqual(spinRec.value(), 5)
+ spinSend.setValue(3)
+ self.assertEqual(spinRec.value(), 3)
+ self.assertEqual(spinSend.value(), 3)
+
+ def testSetValue(self):
+ """Direct signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
+ spinSend = QSpinBox()
+ spinRec = QSpinBox()
+
+ spinRec.setValue(5)
+ spinSend.setValue(42)
+
+ spinSend.valueChanged.connect(spinRec.setValue)
+ self.assertEqual(spinRec.value(), 5)
+ self.assertEqual(spinSend.value(), 42)
+ spinSend.valueChanged.emit(3)
+
+ self.assertEqual(spinRec.value(), 3)
+ # Direct emission shouldn't change the value of the emitter
+ self.assertEqual(spinSend.value(), 42)
+
+ spinSend.valueChanged.emit(66)
+ self.assertEqual(spinRec.value(), 66)
+ self.assertEqual(spinSend.value(), 42)
if __name__ == '__main__':
diff --git a/sources/pyside6/tests/signals/signal_emission_test.py b/sources/pyside6/tests/signals/signal_emission_test.py
index 862a03faa..b31d89c2f 100644
--- a/sources/pyside6/tests/signals/signal_emission_test.py
+++ b/sources/pyside6/tests/signals/signal_emission_test.py
@@ -14,47 +14,47 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL, SLOT, QProcess, QTimeLine
+from PySide6.QtCore import QObject, Signal, SIGNAL, QProcess, QTimeLine
-from helper.basicpyslotcase import BasicPySlotCase
-from helper.usesqcoreapplication import UsesQCoreApplication
+from helper.usesqapplication import UsesQApplication
-class ArgsOnEmptySignal(UsesQCoreApplication):
+class ArgsOnEmptySignal(UsesQApplication):
'''Trying to emit a signal without arguments passing some arguments'''
def testArgsToNoArgsSignal(self):
'''Passing arguments to a signal without arguments'''
process = QProcess()
- self.assertRaises(TypeError, process.emit, SIGNAL('started()'), 42)
+ self.assertRaises(TypeError, process.started.emit, 42)
-class MoreArgsOnEmit(UsesQCoreApplication):
+class MoreArgsOnEmit(UsesQApplication):
'''Trying to pass more args than needed to emit (signals with args)'''
def testMoreArgs(self):
'''Passing more arguments than needed'''
process = QProcess()
- self.assertRaises(TypeError, process.emit, SIGNAL('finished(int)'), 55, 55)
+ self.assertRaises(TypeError, process.finished.emit, 55, QProcess.ExitStatus.NormalExit, 42)
-class Dummy(QObject):
- '''Dummy class'''
- pass
+class Sender(QObject):
+ '''Sender class'''
+ dummy = Signal()
+ dummy_int = Signal(int)
-class PythonSignalToCppSlots(UsesQCoreApplication):
+
+class PythonSignalToCppSlots(UsesQApplication):
'''Connect python signals to C++ slots'''
def testWithoutArgs(self):
'''Connect python signal to QTimeLine.toggleDirection()'''
timeline = QTimeLine()
- dummy = Dummy()
- QObject.connect(dummy, SIGNAL('dummy()'),
- timeline, SLOT('toggleDirection()'))
+ sender = Sender()
+ sender.dummy.connect(timeline.toggleDirection)
orig_dir = timeline.direction()
- dummy.emit(SIGNAL('dummy()'))
+ sender.dummy.emit()
new_dir = timeline.direction()
if orig_dir == QTimeLine.Forward:
@@ -65,17 +65,16 @@ class PythonSignalToCppSlots(UsesQCoreApplication):
def testWithArgs(self):
'''Connect python signals to QTimeLine.setCurrentTime(int)'''
timeline = QTimeLine()
- dummy = Dummy()
+ sender = Sender()
- QObject.connect(dummy, SIGNAL('dummy(int)'),
- timeline, SLOT('setCurrentTime(int)'))
+ sender.dummy_int.connect(timeline.setCurrentTime)
current = timeline.currentTime()
- dummy.emit(SIGNAL('dummy(int)'), current + 42)
+ sender.dummy_int.emit(current + 42)
self.assertEqual(timeline.currentTime(), current + 42)
-class CppSignalsToCppSlots(UsesQCoreApplication):
+class CppSignalsToCppSlots(UsesQApplication):
'''Connection between C++ slots and signals'''
def testWithoutArgs(self):
@@ -83,13 +82,13 @@ class CppSignalsToCppSlots(UsesQCoreApplication):
process = QProcess()
timeline = QTimeLine()
- QObject.connect(process, SIGNAL('finished(int, QProcess::ExitStatus)'),
- timeline, SLOT('toggleDirection()'))
+ process.finished.connect(timeline.toggleDirection)
orig_dir = timeline.direction()
process.start(sys.executable, ['-c', '"print 42"'])
- process.waitForFinished()
+ self.assertTrue(process.waitForStarted())
+ self.assertTrue(process.waitForFinished())
new_dir = timeline.direction()
@@ -107,25 +106,25 @@ def someSlot(args=None):
called = True
-class DynamicSignalsToFuncPartial(UsesQCoreApplication):
+class DynamicSignalsToFuncPartial(UsesQApplication):
def testIt(self):
global called
called = False
- o = QObject()
- o.connect(o, SIGNAL("ASignal()"), functools.partial(someSlot, "partial .."))
- o.emit(SIGNAL("ASignal()"))
+ o = Sender()
+ o.dummy.connect(functools.partial(someSlot, "partial .."))
+ o.dummy.emit()
self.assertTrue(called)
-class EmitUnknownType(UsesQCoreApplication):
+class EmitUnknownType(UsesQApplication):
def testIt(self):
a = QObject()
a.connect(SIGNAL('foobar(Dummy)'), lambda x: 42) # Just connect with an unknown type
self.assertRaises(TypeError, a.emit, SIGNAL('foobar(Dummy)'), 22)
-class EmitEnum(UsesQCoreApplication):
+class EmitEnum(UsesQApplication):
"""Test emission of enum arguments"""
def slot(self, arg):
diff --git a/sources/pyside6/tests/signals/signal_manager_refcount_test.py b/sources/pyside6/tests/signals/signal_manager_refcount_test.py
index 31d3bc85e..955d5b65b 100644
--- a/sources/pyside6/tests/signals/signal_manager_refcount_test.py
+++ b/sources/pyside6/tests/signals/signal_manager_refcount_test.py
@@ -12,11 +12,12 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL
+from PySide6.QtCore import QObject
class SignalManagerRefCount(unittest.TestCase):
- """Simple test case to check if the signal_manager is erroneously incrementing the object refcounter"""
+ """Simple test case to check if the signal_manager is erroneously incrementing the
+ object refcounter."""
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testObjectRefcount(self):
@@ -27,10 +28,9 @@ class SignalManagerRefCount(unittest.TestCase):
refcount = sys.getrefcount(obj)
obj.destroyed.connect(callback)
self.assertEqual(refcount, sys.getrefcount(obj))
- QObject.disconnect(obj, SIGNAL('destroyed()'), callback)
+ obj.destroyed.disconnect(callback)
self.assertEqual(refcount, sys.getrefcount(obj))
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/signal_newenum_test.py b/sources/pyside6/tests/signals/signal_newenum_test.py
new file mode 100644
index 000000000..5fbb875af
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_newenum_test.py
@@ -0,0 +1,50 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Qt, Slot, Signal
+
+
+class Receiver(QObject):
+ def __init__(self):
+ super().__init__()
+ self.result = 0
+
+ @Slot(Qt.Alignment, str)
+ def handler(self, e, s):
+ print('handler', e, "type=", type(e).__name__, s)
+ self.result += 1
+
+
+class Sender(QObject):
+ test_sig = Signal(Qt.AlignmentFlag, str)
+
+ def __init__(self):
+ super().__init__()
+
+ def emit_test_sig(self):
+ self.test_sig.emit(Qt.AlignLeft, "bla")
+
+
+class TestSignalNewEnum(unittest.TestCase):
+ """Test for PYSIDE-2095, signals with new enums in Python 3.11."""
+
+ def testIt(self):
+ sender = Sender()
+ receiver = Receiver()
+ sender.test_sig.connect(receiver.handler)
+
+ sender.emit_test_sig()
+ self.assertEqual(receiver.result, 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_object_test.py b/sources/pyside6/tests/signals/signal_object_test.py
index 1f60b4c3a..607f51813 100644
--- a/sources/pyside6/tests/signals/signal_object_test.py
+++ b/sources/pyside6/tests/signals/signal_object_test.py
@@ -12,7 +12,7 @@ from init_paths import init_test_paths
init_test_paths(False)
from PySide6.QtCore import QTimer, Signal, QObject, Slot, Qt
-from helper.usesqcoreapplication import UsesQCoreApplication
+from helper.usesqapplication import UsesQApplication
class MyObject(QTimer):
@@ -37,7 +37,7 @@ class MyObject(QTimer):
self._o = o
-class SignalObjectTest(UsesQCoreApplication):
+class SignalObjectTest(UsesQApplication):
def cb(self):
self._cb_called = True
self.app.exit()
diff --git a/sources/pyside6/tests/signals/signal_signature_test.py b/sources/pyside6/tests/signals/signal_signature_test.py
index 7477f6243..e8f08b2d9 100644
--- a/sources/pyside6/tests/signals/signal_signature_test.py
+++ b/sources/pyside6/tests/signals/signal_signature_test.py
@@ -13,13 +13,17 @@ from init_paths import init_test_paths
init_test_paths(False)
from PySide6.QtCore import QObject, Signal, SIGNAL, SLOT
-from helper.usesqcoreapplication import UsesQCoreApplication
+from helper.usesqapplication import UsesQApplication
called = False
name = "Old"
+class Sender(QObject):
+ dummySignal = Signal()
+
+
class Obj(QObject):
dummySignalArgs = Signal(str)
numberSignal = Signal(int)
@@ -50,7 +54,7 @@ def callback_empty():
pass
-class TestConnectNotifyWithNewStyleSignals(UsesQCoreApplication):
+class TestConnectNotifyWithNewStyleSignals(UsesQApplication):
'''Test case for signal signature received by QObject::connectNotify().'''
def testOldStyle(self):
@@ -78,9 +82,9 @@ class TestConnectNotifyWithNewStyleSignals(UsesQCoreApplication):
def testStaticSlot(self):
global called
- sender = Obj()
- sender.connect(sender, SIGNAL("dummySignal()"), Obj.static_method)
- sender.emit(SIGNAL("dummySignal()"))
+ sender = Sender()
+ sender.dummySignal.connect(Obj.static_method)
+ sender.dummySignal.emit()
self.assertTrue(called)
def testStaticSlotArgs(self):
@@ -99,4 +103,3 @@ class TestConnectNotifyWithNewStyleSignals(UsesQCoreApplication):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/signals/signal_with_primitive_type_test.py b/sources/pyside6/tests/signals/signal_with_primitive_type_test.py
index a4d5f33a7..01492b333 100644
--- a/sources/pyside6/tests/signals/signal_with_primitive_type_test.py
+++ b/sources/pyside6/tests/signals/signal_with_primitive_type_test.py
@@ -10,7 +10,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QCoreApplication, QObject, QTimeLine, SIGNAL
+from PySide6.QtCore import QCoreApplication, QTimeLine
class SignalPrimitiveTypeTest(unittest.TestCase):
@@ -36,5 +36,3 @@ class SignalPrimitiveTypeTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
-
diff --git a/sources/pyside6/tests/signals/signals.pyproject b/sources/pyside6/tests/signals/signals.pyproject
new file mode 100644
index 000000000..b63724eaf
--- /dev/null
+++ b/sources/pyside6/tests/signals/signals.pyproject
@@ -0,0 +1,19 @@
+{
+ "files": ["anonymous_slot_leak_test.py", "args_dont_match_test.py",
+ "bug_189.py", "bug_311.py", "bug_312.py", "bug_319.py", "bug_79.py",
+ "decorators_test.py", "disconnect_test.py", "invalid_callback_test.py",
+ "lambda_gui_test.py", "lambda_test.py", "leaking_signal_test.py",
+ "multiple_connections_gui_test.py", "multiple_connections_test.py",
+ "pysignal_test.py", "qobject_callable_connect_test.py", "qobject_destroyed_test.py",
+ "qobject_receivers_test.py", "qobject_sender_test.py", "ref01_test.py",
+ "ref02_test.py", "ref03_test.py", "ref04_test.py", "ref05_test.py",
+ "ref06_test.py", "segfault_proxyparent_test.py",
+ "self_connect_test.py", "short_circuit_test.py",
+ "signal2signal_connect_test.py", "signal_across_threads.py",
+ "signal_autoconnect_test.py", "signal_connectiontype_support_test.py",
+ "signal_emission_gui_test.py", "signal_emission_test.py",
+ "signal_enum_test.py", "signal_func_test.py", "signal_manager_refcount_test.py",
+ "signal_newenum_test.py", "signal_number_limit_test.py",
+ "signal_object_test.py", "signal_signature_test.py", "signal_with_primitive_type_test.py",
+ "slot_reference_count_test.py", "static_metaobject_test.py"]
+}
diff --git a/sources/pyside6/tests/signals/slot_reference_count_test.py b/sources/pyside6/tests/signals/slot_reference_count_test.py
index 10a40597e..9d5c73652 100644
--- a/sources/pyside6/tests/signals/slot_reference_count_test.py
+++ b/sources/pyside6/tests/signals/slot_reference_count_test.py
@@ -12,12 +12,14 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL, SLOT
+from PySide6.QtCore import QObject, Signal
class Dummy(QObject):
+ foo = Signal()
+
def dispatch(self):
- self.emit(SIGNAL('foo()'))
+ self.foo.emit()
class PythonSignalRefCount(unittest.TestCase):
@@ -35,10 +37,10 @@ class PythonSignalRefCount(unittest.TestCase):
self.assertEqual(sys.getrefcount(cb), 2)
- QObject.connect(self.emitter, SIGNAL('foo()'), cb)
+ self.emitter.foo.connect(cb)
self.assertEqual(sys.getrefcount(cb), 3)
- QObject.disconnect(self.emitter, SIGNAL('foo()'), cb)
+ self.emitter.foo.disconnect(cb)
self.assertEqual(sys.getrefcount(cb), 2)
@@ -60,7 +62,7 @@ class CppSignalRefCount(unittest.TestCase):
self.emitter.destroyed.connect(cb)
self.assertEqual(sys.getrefcount(cb), 3)
- QObject.disconnect(self.emitter, SIGNAL('destroyed()'), cb)
+ self.emitter.destroyed.disconnect(cb)
self.assertEqual(sys.getrefcount(cb), 2)
diff --git a/sources/pyside6/tests/signals/static_metaobject_test.py b/sources/pyside6/tests/signals/static_metaobject_test.py
index 44d10cd7d..d7bf73e44 100644
--- a/sources/pyside6/tests/signals/static_metaobject_test.py
+++ b/sources/pyside6/tests/signals/static_metaobject_test.py
@@ -14,13 +14,22 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, SIGNAL, Slot
-from helper.usesqcoreapplication import UsesQCoreApplication
+from PySide6.QtCore import QObject, Signal, Slot, SIGNAL
+from helper.usesqapplication import UsesQApplication
+
+
+class Sender(QObject):
+
+ foo = Signal()
+ foo2 = Signal()
class MyObject(QObject):
+
+ foo2 = Signal()
+
def __init__(self, parent=None):
- QObject.__init__(self, parent)
+ super().__init__(parent)
self._slotCalledCount = 0
# this '@Slot()' is needed to get the right sort order in testSharedSignalEmission.
@@ -30,10 +39,11 @@ class MyObject(QObject):
self._slotCalledCount = self._slotCalledCount + 1
-class StaticMetaObjectTest(UsesQCoreApplication):
+class StaticMetaObjectTest(UsesQApplication):
def testSignalPropagation(self):
- o = MyObject()
+ """Old style, dynamic signal creation."""
+ o = QObject()
o2 = MyObject()
# SIGNAL foo not created yet
@@ -55,17 +65,17 @@ class StaticMetaObjectTest(UsesQCoreApplication):
self.assertEqual(o.metaObject().indexOfSignal("foo()"), -1)
def testSharedSignalEmission(self):
- o = QObject()
+ o = Sender()
m = MyObject()
- o.connect(SIGNAL("foo2()"), m.mySlot)
- m.connect(SIGNAL("foo2()"), m.mySlot)
- o.emit(SIGNAL("foo2()"))
+ o.foo2.connect(m.mySlot)
+ m.foo2.connect(m.mySlot)
+ o.foo2.emit()
self.assertEqual(m._slotCalledCount, 1)
del o
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
- m.emit(SIGNAL("foo2()"))
+ m.foo2.emit()
self.assertEqual(m._slotCalledCount, 2)