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
示例#2
0
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()
示例#3
0
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
示例#4
0
文件: qt.py 项目: dyceron/randovania
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
示例#5
0
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)
示例#6
0
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
示例#7
0
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)
示例#8
0
            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()
示例#10
0
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()