回答編集履歴
2
修正時にまぎれた不具合修正。終了処理 _root() -> _root.quit()
test
CHANGED
@@ -258,7 +258,7 @@
|
|
258
258
|
|
259
259
|
def quit(self):
|
260
260
|
self._stop()
|
261
|
-
self._root()
|
261
|
+
self._root.quit()
|
262
262
|
|
263
263
|
def _stop(self): # NOTE: thread-safe
|
264
264
|
with self._mutex:
|
1
不具合修正: UWSC.emit の排他制御が完全でなかったので修正。if is_running ~ after の隙間に別スレッドから終了する余地があった
test
CHANGED
@@ -111,7 +111,7 @@
|
|
111
111
|
import tkinter as tk
|
112
112
|
from dataclasses import dataclass
|
113
113
|
from operator import attrgetter
|
114
|
-
from threading import Thread, Event, Lock
|
114
|
+
from threading import Thread, Event, RLock
|
115
115
|
_get_geometry = attrgetter(*"x y width height".split())
|
116
116
|
|
117
117
|
def gen_timer(root, gen, timer=None): # 簡易実装版、キャンセル可能なタイマー
|
@@ -202,7 +202,7 @@
|
|
202
202
|
self._tasks = []
|
203
203
|
self._threads = []
|
204
204
|
self._event = Event()
|
205
|
-
self._mutex = Lock()
|
205
|
+
self._mutex = RLock()
|
206
206
|
|
207
207
|
def sleep(self, interval):
|
208
208
|
return interval
|
@@ -231,8 +231,9 @@
|
|
231
231
|
self.tk_root.after_idle(thread.start)
|
232
232
|
|
233
233
|
def emit(self, func, *args, **kw): # NOTE: thread-safe
|
234
|
-
i
|
234
|
+
with self._mutex: # <-- ここの同期が正常に保てればスレッド安全
|
235
|
+
if self.is_running:
|
235
|
-
self.tk_root.after_idle(lambda: func(*args, **kw))
|
236
|
+
self.tk_root.after_idle(lambda: func(*args, **kw))
|
236
237
|
|
237
238
|
def run(self):
|
238
239
|
root = self.tk_root
|
@@ -243,6 +244,7 @@
|
|
243
244
|
cancel()
|
244
245
|
root.update_idletasks()
|
245
246
|
root.destroy()
|
247
|
+
|
246
248
|
root.protocol("WM_DELETE_WINDOW", _on_closing)
|
247
249
|
|
248
250
|
root.mainloop()
|
@@ -256,7 +258,7 @@
|
|
256
258
|
|
257
259
|
def quit(self):
|
258
260
|
self._stop()
|
259
|
-
self._root
|
261
|
+
self._root()
|
260
262
|
|
261
263
|
def _stop(self): # NOTE: thread-safe
|
262
264
|
with self._mutex:
|