qasync icon indicating copy to clipboard operation
qasync copied to clipboard

Allow QEventLoop from QThread

Open corby opened this issue 1 year ago • 0 comments

The current QEventLoop is bound to QApplication. This does not allow the use of the QEventLoop inside QThreads that are spawned off from the main UI thread.

It's a small change to 3 lines (and an import) to generalize the QEventLoop to function in a QThread.run setup that allows both @Slot() and @asyncSlot() to work.

Subject: [PATCH] Allow qasyn.QEventLoop to run in QThread.
---
Index: qasync/__init__.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/qasync/__init__.py b/qasync/__init__.py
--- a/qasync/__init__.py	(revision a6eb8e55a112e1c115fd1ed4cd8f120abb097a55)
+++ b/qasync/__init__.py	(date 1720290946911)
@@ -82,25 +82,25 @@
 
 if QtModuleName == "PyQt5":
     from PyQt5 import QtWidgets
-    from PyQt5.QtCore import pyqtSlot as Slot
+    from PyQt5.QtCore import pyqtSlot as Slot, QThread
 
     QApplication = QtWidgets.QApplication
 
 elif QtModuleName == "PyQt6":
     from PyQt6 import QtWidgets
-    from PyQt6.QtCore import pyqtSlot as Slot
+    from PyQt6.QtCore import pyqtSlot as Slot, QThread
 
     QApplication = QtWidgets.QApplication
 
 elif QtModuleName == "PySide2":
     from PySide2 import QtWidgets
-    from PySide2.QtCore import Slot
+    from PySide2.QtCore import Slot, QThread
 
     QApplication = QtWidgets.QApplication
 
 elif QtModuleName == "PySide6":
     from PySide6 import QtWidgets
-    from PySide6.QtCore import Slot
+    from PySide6.QtCore import Slot, QThread
 
     QApplication = QtWidgets.QApplication
 
@@ -401,7 +401,7 @@
             self.run_forever()
         finally:
             future.remove_done_callback(stop)
-        self.__app.processEvents()  # run loop one last time to process all the events
+        self.__app.eventDispatcher().processEvents()  # run loop one last time to process all the events
         if not future.done():
             raise RuntimeError("Event loop stopped before Future completed.")
 
@@ -416,7 +416,10 @@
 
         self.__log_debug("Stopping event loop...")
         self.__is_running = False
-        self.__app.exit()
+        if isinstance(self.__app, QThread):
+            self.__app.quit()
+        else:
+            self.__app.exit()
         self.__log_debug("Stopped event loop")
 
     def is_running(self):

corby avatar Jul 06 '24 18:07 corby