aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Herrmann <adrian.herrmann@qt.io>2024-01-31 18:13:00 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2024-02-08 11:28:34 +0100
commitbf0f779125afae2c6c995cea5dc5553da8e9da77 (patch)
tree1efc31aa36ff44d4003c07836c88d7385e6e52a3
parenta84fbebc64d392061c319ffc72d1be967b5c6b97 (diff)
QTimer: Fix singleShot overload with context
The singleShot overload with context had a problem where if the functor was a slot of a QObject, it would not have a sender when it should. To fix this, the newly added QObject.connect() overload with context is used. Change-Id: I654c09efb0d1b37ea0c014e9f17cd5e1913d1a96 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> (cherry picked from commit 6b227000f28c82e189f3cc26275ca7a930f75e2f) Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--sources/pyside6/PySide6/glue/qtcore.cpp50
-rw-r--r--sources/pyside6/tests/QtCore/qtimer_singleshot_test.py11
-rw-r--r--sources/pyside6/tests/signals/qobject_sender_test.py7
3 files changed, 44 insertions, 24 deletions
diff --git a/sources/pyside6/PySide6/glue/qtcore.cpp b/sources/pyside6/PySide6/glue/qtcore.cpp
index ed1cb100f..94dc915a0 100644
--- a/sources/pyside6/PySide6/glue/qtcore.cpp
+++ b/sources/pyside6/PySide6/glue/qtcore.cpp
@@ -1059,28 +1059,9 @@ timer->start(%1);
// @snippet qtimer-singleshot-2
// @snippet qtimer-singleshot-functor-context
-Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
-if (PyObject_TypeCheck(%3, PySideSignalInstance_TypeF())) {
- auto *timerType = Shiboken::SbkType<QTimer>();
- auto *pyTimer = timerType->tp_new(Shiboken::SbkType<QTimer>(), emptyTuple, nullptr);
- timerType->tp_init(pyTimer, emptyTuple, nullptr);
- QTimer * timer = %CONVERTTOCPP[QTimer *](pyTimer);
- timer->setSingleShot(true);
- PySideSignalInstance *signalInstance = reinterpret_cast<PySideSignalInstance *>(%2);
- Shiboken::AutoDecRef signalSignature(Shiboken::String::fromFormat("2%s", PySide::Signal::getSignature(signalInstance)));
- Shiboken::AutoDecRef result(
- PyObject_CallFunction(PySide::PySideName::qtConnect(), "OsOO",
- pyTimer,
- SIGNAL(timeout()),
- %3,
- PySide::Signal::getObject(signalInstance),
- signalSignature.object())
- );
- timer->connect(timer, &QTimer::timeout, timer, &QObject::deleteLater, Qt::DirectConnection);
- Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(pyTimer));
- Py_XDECREF(pyTimer);
- timer->start(%1);
-} else {
+auto msec = %1;
+if (msec == 0) {
+ Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
auto *callable = %PYARG_3;
auto cppCallback = [callable]()
{
@@ -1091,7 +1072,30 @@ if (PyObject_TypeCheck(%3, PySideSignalInstance_TypeF())) {
};
Py_INCREF(callable);
- %CPPSELF.%FUNCTION_NAME(%1, %2, cppCallback);
+ %CPPSELF.%FUNCTION_NAME(msec, %2, cppCallback);
+} else {
+ Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
+ auto *timerType = Shiboken::SbkType<QTimer>();
+ auto newFunc = timerType->tp_new;
+ auto initFunc = timerType->tp_init;
+ auto *pyTimer = newFunc(Shiboken::SbkType<QTimer>(), emptyTuple, nullptr);
+ initFunc(pyTimer, emptyTuple, nullptr);
+
+ QTimer * timer = %CONVERTTOCPP[QTimer *](pyTimer);
+ timer->setSingleShot(true);
+
+ Shiboken::AutoDecRef result(
+ PyObject_CallMethod(pyTimer, "connect", "OsOO",
+ pyTimer,
+ SIGNAL(timeout()),
+ %PYARG_2,
+ %PYARG_3)
+ );
+
+ timer->connect(timer, &QTimer::timeout, timer, &QObject::deleteLater, Qt::DirectConnection);
+ Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(pyTimer));
+ Py_XDECREF(pyTimer);
+ timer->start(msec);
}
// @snippet qtimer-singleshot-functor-context
diff --git a/sources/pyside6/tests/QtCore/qtimer_singleshot_test.py b/sources/pyside6/tests/QtCore/qtimer_singleshot_test.py
index 1392281fa..9718a2427 100644
--- a/sources/pyside6/tests/QtCore/qtimer_singleshot_test.py
+++ b/sources/pyside6/tests/QtCore/qtimer_singleshot_test.py
@@ -85,6 +85,17 @@ class TestSingleShot(UsesQApplication):
self.assertTrue(thread.called)
self.assertEqual(self.qthread, thread.qthread)
+ def testSingleShotWithContextZero(self):
+ thread = ThreadForContext()
+ thread.start()
+ thread.context.moveToThread(thread)
+ QTimer.singleShot(0, thread.context, self.callback)
+ self.app.exec()
+ thread.wait()
+ self.assertTrue(self.called)
+ self.assertTrue(thread.called)
+ self.assertEqual(self.qthread, thread.qthread)
+
class SigEmitter(QObject):
diff --git a/sources/pyside6/tests/signals/qobject_sender_test.py b/sources/pyside6/tests/signals/qobject_sender_test.py
index a7cda69f7..485584ec2 100644
--- a/sources/pyside6/tests/signals/qobject_sender_test.py
+++ b/sources/pyside6/tests/signals/qobject_sender_test.py
@@ -73,6 +73,12 @@ class ObjectSenderWithQAppTest(UsesQApplication):
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()
@@ -105,4 +111,3 @@ class ObjectSenderWithQAppCheckOnReceiverTest(UsesQApplication):
if __name__ == '__main__':
unittest.main()
-