def loop(request, application): lp = qasync.QEventLoop(application) asyncio.set_event_loop(lp) additional_exceptions = [] def fin(): sys.excepthook = orig_excepthook try: lp.close() finally: asyncio.set_event_loop(None) for exc in additional_exceptions: if (os.name == "nt" and isinstance(exc["exception"], WindowsError) and exc["exception"].winerror == 6): # ignore Invalid Handle Errors continue raise exc["exception"] def except_handler(loop, ctx): additional_exceptions.append(ctx) def excepthook(type, *args): lp.stop() orig_excepthook(type, *args) orig_excepthook = sys.excepthook sys.excepthook = excepthook lp.set_exception_handler(except_handler) request.addfinalizer(fin) return lp
def main(): parser = argparse.ArgumentParser() parser.add_argument("--nintendont", help="Connect to the given IP via the Nintendont protocol instead.") args = parser.parse_args() app = QCoreApplication(sys.argv) os.environ['QT_API'] = "PySide2" import qasync loop = qasync.QEventLoop(app) asyncio.set_event_loop(loop) logging.config.dictConfig({ 'version': 1, 'formatters': { 'default': { 'format': '[%(asctime)s] [%(levelname)s] [%(name)s] %(funcName)s: %(message)s', } }, 'handlers': { 'default': { 'level': 'DEBUG', 'formatter': 'default', 'class': 'logging.StreamHandler', 'stream': 'ext://sys.stdout', # Default is stderr }, }, 'loggers': { }, 'root': { 'level': 'DEBUG', 'handlers': ['default'], }, }) def catch_exceptions(t, val, tb): global should_quit should_quit = True old_hook(t, val, tb) def catch_exceptions_async(loop, context): if 'future' in context: future: asyncio.Future = context['future'] logging.exception(context["message"], exc_info=future.exception()) else: logging.critical(str(context)) sys.excepthook = catch_exceptions loop.set_exception_handler(catch_exceptions_async) if args.nintendont is not None: backend = NintendontBackend(args.nintendont) else: backend = DolphinBackend() with loop: try: asyncio.get_event_loop().run_until_complete(worker(app, backend)) finally: app.quit()
def init_qtapp(): global qtapp, loop if qtapp is None: qtapp = QtWidgets.QApplication(sys.argv) loop = qasync.QEventLoop(qtapp) asyncio.set_event_loop(loop) qtapp.processEvents() return qtapp, loop
def create_loop(app: QtWidgets.QApplication) -> asyncio.AbstractEventLoop: os.environ['QT_API'] = "PySide2" import qasync loop: asyncio.AbstractEventLoop = qasync.QEventLoop(app) asyncio.set_event_loop(loop) sys.excepthook = catch_exceptions loop.set_exception_handler(catch_exceptions_async) return loop
def _setup_asyncio_event_loop(): from PyQt5.QtWidgets import QApplication import qasync import asyncio if isinstance(asyncio.get_event_loop(), qasync.QEventLoop): print("Note: qasync event loop already set up.") else: qapp = QApplication.instance() loop = qasync.QEventLoop(qapp, already_running=True) asyncio.set_event_loop(loop)
def get_event_loop() -> asyncio.AbstractEventLoop: """ Get the asyncio.AbstractEventLoop for the main Qt application thread. The QCoreApplication instance must already have been created. Must only be called from the main Qt application thread. """ try: # Python >= 3.7 get_running_loop = asyncio.get_running_loop # type: ignore except AttributeError: get_running_loop = asyncio._get_running_loop # type: ignore app = QCoreApplication.instance() if app is None: raise RuntimeError("QCoreApplication is not running") if app.thread() is not QThread.currentThread(): raise RuntimeError("Called from non-main thread") loop: Optional[asyncio.AbstractEventLoop] try: loop = get_running_loop() except RuntimeError: loop = None else: if loop is not None: return loop qt_api = os.environ.get("QT_API", "").lower() if qt_api == "pyqt5": os.environ["QT_API"] = "PyQt5" elif qt_api == "pyside2": os.environ["QT_API"] = "PySide2" import qasync if loop is None: loop = qasync.QEventLoop(app) # Do not use qasync.QEventLoop's default executor which uses QThread # based pool and exhibits https://github.com/numpy/numpy/issues/11551 loop.set_default_executor(futures.ThreadPoolExecutor()) return loop
def run_asynchronous(window_class): qt_app = QtWidgets.QApplication(sys.argv) translator = QtCore.QTranslator(qt_app) locale = QtCore.QLocale.system().name() i18n_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'i18n') translator.load("qubesmanager_{!s}.qm".format(locale), i18n_dir) qt_app.installTranslator(translator) QtCore.QCoreApplication.installTranslator(translator) qt_app.setOrganizationName("The Qubes Project") qt_app.setOrganizationDomain("http://qubes-os.org") qt_app.lastWindowClosed.connect(loop_shutdown) qubes_app = qubesadmin.Qubes() loop = qasync.QEventLoop(qt_app) asyncio.set_event_loop(loop) dispatcher = events.EventsDispatcher(qubes_app) window = window_class(qt_app, qubes_app, dispatcher) if hasattr(window, "setup_application"): window.setup_application() window.show() try: loop.run_until_complete( asyncio.ensure_future(dispatcher.listen_for_events())) except asyncio.CancelledError: pass except Exception: # pylint: disable=broad-except loop_shutdown() exc_type, exc_value, exc_traceback = sys.exc_info()[:3] handle_exception(exc_type, exc_value, exc_traceback)
self.button.setText("Start") def on_progress(self, done: int, total: int) -> None: """ Updates the progress bar when scheduler finishes a task. """ if done == 0: self.progress.setMaximum(total) self.progress.setValue(done) def closeEvent(self, event: QtGui.QCloseEvent) -> None: """ Terminates the scheduler when the window exits. """ if self.scheduler: self.scheduler.terminate() if __name__ == "__main__": app = QApplication(sys.argv) # Important: set the event loop using `qasync`. loop = qasync.QEventLoop(app) asyncio.set_event_loop(loop) window = Window() window.show() with loop: sys.exit(loop.run_forever())
def test_can_function_as_context_manager(application): """Verify that a QEventLoop can function as its own context manager.""" with qasync.QEventLoop(application) as loop: assert isinstance(loop, qasync.QEventLoop) loop.call_soon(loop.stop) loop.run_forever()
def main(*args): import sys if len(args) == 0: args = sys.argv else: args = [sys.executable] + list(args) print("args", args) if len(args) > 1: if args[1] == "register" or args[1] == "install": from .includes.RegisterRegistry import install return install() elif args[1] == "unregister" or args[1] == "uninstall": from .includes.RegisterRegistry import install return install("uninstall") elif args[1] == "-v" or args[1] == "--version": import clickpoints print(clickpoints.__version__) return elif args[1] == "ffmpeg": import imageio import glob import os # check for ffmpeg try: # check if imageio already has an exe file imageio.plugins.ffmpeg.get_exe() print("ffmpeg found from imageio") except imageio.core.fetching.NeedDownloadError: # try to find an ffmpeg.exe in the ClickPoints folder files = glob.glob( os.path.join(os.path.dirname(__file__), "..", "ffmpeg*.exe")) files.extend( glob.glob( os.path.join(os.path.dirname(__file__), "..", "external", "ffmpeg*.exe"))) # if an ffmpeg exe has been found, set the environmental variable accordingly if len(files): print("ffmpeg found", files[0]) os.environ['IMAGEIO_FFMPEG_EXE'] = files[0] # if not, try to download it else: print("try to download ffmpeg") imageio.plugins.ffmpeg.download() return from clickpoints import print_status # print print_status() """ some magic to prevent PyQt5 from swallowing exceptions """ # Back up the reference to the exceptionhook sys._excepthook = sys.excepthook # Set the exception hook to our wrapping function sys.excepthook = lambda *args: sys._excepthook(*args) from qtpy import QtCore, QtWidgets, QtGui import sys import ctypes from clickpoints.Core import ClickPointsWindow from clickpoints.includes import LoadConfig import qasync import asyncio from clickpoints import define_paths define_paths() app = QtWidgets.QApplication(args) loop = qasync.QEventLoop(app) asyncio.set_event_loop(loop) app.loop = loop # set an application id, so that windows properly stacks them in the task bar if sys.platform[:3] == 'win': myappid = 'fabrybiophysics.clickpoints' # arbitrary string ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid) # load config and exec addon code config = LoadConfig(*args) with loop: # init and open the ClickPoints window window = ClickPointsWindow(config, app) window.show() loop.run_forever()