diff --git a/TermTk/TTkCore/signal.py b/TermTk/TTkCore/signal.py index bff42780..3f6325d6 100644 --- a/TermTk/TTkCore/signal.py +++ b/TermTk/TTkCore/signal.py @@ -60,9 +60,26 @@ __all__ = ['pyTTkSlot', 'pyTTkSignal'] # from typing import TypeVar, TypeVarTuple, Generic, List from inspect import getfullargspec, iscoroutinefunction from types import LambdaType -from threading import Lock, Thread +from threading import Lock import asyncio +import importlib.util + +if importlib.util.find_spec('pyodideProxy'): + pass +else: + from threading import Thread + import asyncio + + def _async_runner(coros): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + loop.run_until_complete(asyncio.gather(*coros)) + loop.close() + + def _run_coroutines(coros): + Thread(target=_async_runner, args=(coros,)).start() + def pyTTkSlot(*args): def pyTTkSlot_d(func): # Add signature attributes to the function @@ -136,12 +153,6 @@ class pyTTkSignal(): if slot in self._connected_slots: del self._connected_slots[slot] - def _async_runner(self, coros): - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - loop.run_until_complete(asyncio.gather(*coros)) - loop.close() - def emit(self, *args, **kwargs) -> None: if not self._mutex.acquire(False): return if len(args) != len(self._types): @@ -151,7 +162,7 @@ class pyTTkSignal(): slot(*args[sl], **kwargs) if self._connected_async_slots: coros = [slot(*args[sl], **kwargs) for slot,sl in self._connected_async_slots.copy().items()] - Thread(target=self._async_runner, args=(coros,)).start() + _run_coroutines(coros) self._mutex.release() def clear(self): @@ -165,4 +176,4 @@ class pyTTkSignal(): def forward(self): def _ret(*args, **kwargs) -> None: self.emit(*args, **kwargs) - return _ret + return _ret \ No newline at end of file diff --git a/tests/t.ui/test.ui.034.async.01.py b/tests/t.ui/test.ui.034.async.01.py new file mode 100755 index 00000000..d326ae88 --- /dev/null +++ b/tests/t.ui/test.ui.034.async.01.py @@ -0,0 +1,49 @@ +import asyncio +import inspect +import sys, os +import time + +sys.path.append(os.path.join(sys.path[0],'..')) +import TermTk as ttk + +root = ttk.TTk(layout=ttk.TTkVBoxLayout()) +res = ttk.TTkLabel(parent=root) +num = ttk.TTkLabel(parent=root, text=1) +button_add = ttk.TTkButton(parent=root, text="+") +button_add.clicked.connect(lambda: num.setText(int(num.text()) + 1)) +button_call = ttk.TTkButton(parent=root, text="Call") +ttk.TTkButton(parent=root, text="Quit").clicked.connect(ttk.TTkHelper.quit) + +@ttk.pyTTkSlot() +def call0(): + res.setText("0 Calling...") + time.sleep(1) + res.setText("0 Calling... - DONE") + +async def call1(): + res.setText("1 Calling...") + await asyncio.sleep(3) + res.setText("1 Calling... - DONE") + +@ttk.pyTTkSlot() +async def call2(): + res.setText("2 Calling...") + await asyncio.sleep(5) + res.setText("2 Calling... - DONE") + +@ttk.pyTTkSlot(int) +async def call3(val): + res.setText(f"3 Calling... {val}") + await asyncio.sleep(5) + res.setText(f"3 Calling... {val} - DONE") + +print(inspect.iscoroutinefunction(call0)) +print(inspect.iscoroutinefunction(call1)) +print(inspect.iscoroutinefunction(call2)) +print(inspect.iscoroutinefunction(call3)) + +button_call.clicked.connect(call0) +button_call.clicked.connect(call1) +button_call.clicked.connect(call2) + +root.mainloop() \ No newline at end of file