Skip to content

Commit 654b569

Browse files
committed
added call_nosync
1 parent da93f8a commit 654b569

4 files changed

Lines changed: 72 additions & 5 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ use `root` as the master.
122122
- same as `.patch()`
123123
- `tkthread.call(func, *args, **kw)`
124124
- call `func` on the main thread, with arguments and keyword arguments.
125+
- waits for return value (or raises error)
126+
- `tkthread.call_nosync(func, *args, **kw)`
127+
- call `func` on the main thread, with arguments and keyword arguments.
128+
- returns immediately, ignore return `func` return or error.
125129
- `@tkthread.called_on_main`
126130
- decorator to dispatch the function call on the main thread from the calling thread.
127131
- `@tkthread.main()`

tests/test_tkthread.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,57 @@ def func():
340340
self.root.update()
341341

342342
self.assertIs(d['called'], True)
343+
@tkthread.main()
344+
def _():
345+
d['called'] = True
346+
347+
t = threading.current_thread()
348+
343349
self.assertIs(d['thread'], t)
344350

351+
def test_main_nosync(self):
352+
d = dict()
353+
354+
main_thread = threading.current_thread()
355+
356+
@thread_start()
357+
def tstart_nosync():
358+
359+
@tkthread.main(sync=False)
360+
def func():
361+
d['nosync'] = threading.current_thread()
362+
363+
@call_until(4.0)
364+
def alive():
365+
return tstart_nosync.is_alive()
366+
367+
self.assertFalse(tstart_nosync.is_alive())
368+
self.assertFalse(alive)
369+
self.assertFalse('nosync' in d)
370+
371+
@thread_start()
372+
def tstart():
373+
@tkthread.main(sync=True)
374+
def func():
375+
d['sync'] = threading.current_thread()
376+
377+
@call_until(4.0)
378+
def has_thread():
379+
self.root.update()
380+
return 'sync' not in d
381+
382+
383+
@call_until(4.0)
384+
def tstart_timeout():
385+
self.root.update()
386+
return tstart.is_alive()
387+
388+
self.assertTrue('nosync' in d)
389+
self.assertTrue('sync' in d)
390+
391+
self.assertIs(d['sync'], main_thread)
392+
self.assertIs(d['nosync'], main_thread)
393+
345394
def test_current(self):
346395
d = dict(called=False, thread=False)
347396
@tkthread.current()

tkthread/__init__.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,16 @@ def run(func):
103103

104104
from ._version import __version__
105105
from ._willdispatch import (
106-
tkinstall, main, current, call, called_on_main
106+
tkinstall, main, current,
107+
call, call_nosync,
108+
called_on_main
107109
)
108110

109-
__all__ = ['TkThread', 'tk', '__version__',
110-
'tkinstall', 'main', 'current', 'call', 'patch']
111+
__all__ = [
112+
'TkThread', 'tk', '__version__',
113+
'tkinstall', 'patch', 'main', 'current',
114+
'call', 'call_nosync',
115+
]
111116

112117
patch = tkinstall # Issue #4
113118

tkthread/_willdispatch.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,12 @@ def sync_wrapped(_func=func, _ev=ev):
231231
ev.wait()
232232

233233
else:
234-
_ensure_after_idle(w, func)
235-
234+
th = threading.Thread(
235+
target=_ensure_after_idle,
236+
args=(w, func),
237+
name='tkthread.main')
238+
th.daemon = True
239+
th.start()
236240

237241
return func
238242
return wrapped
@@ -275,6 +279,11 @@ def call(func, *args, **kwargs):
275279
return _callsync(True, func, args, kwargs)
276280

277281

282+
def call_nosync(func, *args, **kwargs):
283+
"""Enqueue the function for calling on the main thread, immediately return."""
284+
return _callsync(False, func, args, kwargs)
285+
286+
278287
class called_on_main:
279288
"""Decorator to cause function call to execute on the main thread.
280289

0 commit comments

Comments
 (0)