回答編集履歴
4
不要な変数名を修正。
test
CHANGED
@@ -278,7 +278,7 @@
|
|
278
278
|
balloon.destroy()
|
279
279
|
else:
|
280
280
|
def gen_timer(gen): # ジェネレーターをタイマーで処理する(簡易版)
|
281
|
-
def _next(tid,
|
281
|
+
def _next(tid, _):
|
282
282
|
timer.kill_timer(tid)
|
283
283
|
if interval := next(gen, None):
|
284
284
|
timer.set_timer(interval*1000, _next)
|
3
追記: win32gui でタイマー&メッセージループを使う実装
test
CHANGED
@@ -249,3 +249,50 @@
|
|
249
249
|
if __name__ == '__main__':
|
250
250
|
main()
|
251
251
|
```
|
252
|
+
|
253
|
+
----
|
254
|
+
## 追記: win32gui でタイマー&メッセージループを使う実装
|
255
|
+
|
256
|
+
自分の環境では問題の再現が難しいので、(もしくは再現条件を把握できていない)
|
257
|
+
解決に繋がるかはわかりませんが、問題の懸念要素は取り除けると思います。
|
258
|
+
|
259
|
+
上述の「ジェネレーターをタイマーで処理する」アプローチの win32gui 版です。
|
260
|
+
pywin32 では API の SetTimer/KillTimer を直接扱わず、timer モジュールが提供されてるようです。
|
261
|
+
|
262
|
+
コードは差分のみ。balloon生成後
|
263
|
+
```python
|
264
|
+
if 0:
|
265
|
+
import time
|
266
|
+
time.sleep(3)
|
267
|
+
|
268
|
+
# 内容と位置を更新
|
269
|
+
balloon.update(message="Updated Content!", x=500, y=300)
|
270
|
+
|
271
|
+
time.sleep(3)
|
272
|
+
|
273
|
+
# さらに更新
|
274
|
+
balloon.update(message="Final Update!")
|
275
|
+
time.sleep(3)
|
276
|
+
|
277
|
+
# 終了
|
278
|
+
balloon.destroy()
|
279
|
+
else:
|
280
|
+
def gen_timer(gen): # ジェネレーターをタイマーで処理する(簡易版)
|
281
|
+
def _next(tid, time):
|
282
|
+
timer.kill_timer(tid)
|
283
|
+
if interval := next(gen, None):
|
284
|
+
timer.set_timer(interval*1000, _next)
|
285
|
+
timer.set_timer(0, _next)
|
286
|
+
|
287
|
+
def timeline(balloon): # time.sleep の替わりに、ジェネレーターで実装
|
288
|
+
yield 3
|
289
|
+
balloon.update(message="Updated Content!", x=500, y=300)
|
290
|
+
yield 3
|
291
|
+
balloon.update(message="Final Update!")
|
292
|
+
yield 3
|
293
|
+
balloon.destroy()
|
294
|
+
|
295
|
+
gen_timer(timeline(balloon)) # タイマー
|
296
|
+
win32gui.PumpMessages() # メッセージループ
|
297
|
+
|
298
|
+
```
|
2
Animationクラスを継承ではなく移譲に
test
CHANGED
@@ -68,11 +68,10 @@
|
|
68
68
|
alpha: float = -1
|
69
69
|
timeout: int = -1
|
70
70
|
|
71
|
-
class BalloonAnimation
|
71
|
+
class BalloonAnimation:
|
72
|
-
"""
|
73
|
-
|
72
|
+
def __init__(self, balloon):
|
74
|
-
|
73
|
+
self.window, self.label = balloon.window, balloon.label
|
75
|
-
|
74
|
+
|
76
75
|
def _calc_range_step(self, a, b, steps):
|
77
76
|
return (max(a,b) - min(a,b))/steps * (-1 if a > b else 1)
|
78
77
|
|
@@ -142,7 +141,7 @@
|
|
142
141
|
else:
|
143
142
|
label["fg"] = fg
|
144
143
|
|
145
|
-
class BalloonApp
|
144
|
+
class BalloonApp:
|
146
145
|
def __init__(self, *args, **kwargs):
|
147
146
|
window = tk.Toplevel(*args, **kwargs)
|
148
147
|
window.overrideredirect(True) # ウィンドウの枠けし
|
@@ -154,6 +153,7 @@
|
|
154
153
|
|
155
154
|
self.window = window
|
156
155
|
self.label = label
|
156
|
+
self.animation = BalloonAnimation(self)
|
157
157
|
|
158
158
|
def __call__(self, message, **kw) -> None:
|
159
159
|
"""Update balloon info"""
|
@@ -204,10 +204,10 @@
|
|
204
204
|
timeout=8, # 8秒後に非表示
|
205
205
|
)
|
206
206
|
# Demo: 3秒かけてフェードイン
|
207
|
-
yield from balloon.fade(alpha=0.5, duration=3)
|
207
|
+
yield from balloon.animation.fade(alpha=0.5, duration=3)
|
208
208
|
|
209
209
|
# Demo: 点滅表示
|
210
|
-
yield from balloon.blink(duration=3)
|
210
|
+
yield from balloon.animation.blink(duration=3)
|
211
211
|
|
212
212
|
yield 3 # wait 3 sec
|
213
213
|
|
@@ -218,17 +218,17 @@
|
|
218
218
|
yield 3 # wait 3 sec
|
219
219
|
|
220
220
|
# Demo: 移動アニメーション
|
221
|
-
yield from balloon.move(x=200, y=200, duration=3)
|
221
|
+
yield from balloon.animation.move(x=200, y=200, duration=3)
|
222
222
|
|
223
223
|
## 3)
|
224
224
|
balloon("Final update!")
|
225
225
|
|
226
|
-
yield from balloon.resize(width=400, height=400)
|
226
|
+
yield from balloon.animation.resize(width=400, height=400)
|
227
227
|
|
228
228
|
yield 3 # wait 3 sec
|
229
229
|
|
230
230
|
# Demo: フェードアウト
|
231
|
-
yield from balloon.fade(alpha=0, duration=3)
|
231
|
+
yield from balloon.animation.fade(alpha=0, duration=3)
|
232
232
|
|
233
233
|
def main():
|
234
234
|
root = tk.Tk()
|
1
main関数の見通しが悪くなったので、program関数を外部へ移動・名称変更timeline関数へ
test
CHANGED
@@ -190,6 +190,46 @@
|
|
190
190
|
window.deiconify() # 再表示
|
191
191
|
return self
|
192
192
|
|
193
|
+
def timeline(balloon):
|
194
|
+
"""time.sleep を使ったコードをジェネレーターとして実装する
|
195
|
+
|
196
|
+
例:
|
197
|
+
time.sleep(3) => yield 3
|
198
|
+
"""
|
199
|
+
## 1)
|
200
|
+
balloon("Hello, world!", x=50, y=50,
|
201
|
+
font=("", 40),
|
202
|
+
alpha=0.0,
|
203
|
+
fg="#00ffff",
|
204
|
+
timeout=8, # 8秒後に非表示
|
205
|
+
)
|
206
|
+
# Demo: 3秒かけてフェードイン
|
207
|
+
yield from balloon.fade(alpha=0.5, duration=3)
|
208
|
+
|
209
|
+
# Demo: 点滅表示
|
210
|
+
yield from balloon.blink(duration=3)
|
211
|
+
|
212
|
+
yield 3 # wait 3 sec
|
213
|
+
|
214
|
+
## 2)
|
215
|
+
balloon("Updated Content!",
|
216
|
+
font=("", 25),
|
217
|
+
)
|
218
|
+
yield 3 # wait 3 sec
|
219
|
+
|
220
|
+
# Demo: 移動アニメーション
|
221
|
+
yield from balloon.move(x=200, y=200, duration=3)
|
222
|
+
|
223
|
+
## 3)
|
224
|
+
balloon("Final update!")
|
225
|
+
|
226
|
+
yield from balloon.resize(width=400, height=400)
|
227
|
+
|
228
|
+
yield 3 # wait 3 sec
|
229
|
+
|
230
|
+
# Demo: フェードアウト
|
231
|
+
yield from balloon.fade(alpha=0, duration=3)
|
232
|
+
|
193
233
|
def main():
|
194
234
|
root = tk.Tk()
|
195
235
|
if not __debug__:
|
@@ -197,51 +237,11 @@
|
|
197
237
|
# 事例 ⇒ PID が解らず 大量の python.exe がタスクマネージャーに
|
198
238
|
# __debug__ の True/False は Python の起動オプションを参照
|
199
239
|
root.withdraw() # メインウィンドウを非表示
|
200
|
-
balloon = BalloonApp(root)
|
201
|
-
|
202
|
-
def program():
|
203
|
-
"""time.sleep を使ったコードをジェネレーターとして実装する
|
204
|
-
|
205
|
-
例:
|
206
|
-
time.sleep(3) => yield 3
|
207
|
-
"""
|
208
|
-
## 1)
|
209
|
-
balloon("Hello, world!", x=50, y=50,
|
210
|
-
font=("", 40),
|
211
|
-
alpha=0.0,
|
212
|
-
fg="#00ffff",
|
213
|
-
timeout=8, # 8秒後に非表示
|
214
|
-
)
|
215
|
-
# Demo: 3秒かけてフェードイン
|
216
|
-
yield from balloon.fade(alpha=0.5, duration=3)
|
217
|
-
|
218
|
-
# Demo: 点滅表示
|
219
|
-
yield from balloon.blink(duration=3)
|
220
|
-
|
221
|
-
yield 3 # wait 3 sec
|
222
|
-
|
223
|
-
## 2)
|
224
|
-
balloon("Updated Content!",
|
225
|
-
font=("", 25),
|
226
|
-
)
|
227
|
-
yield 3 # wait 3 sec
|
228
|
-
|
229
|
-
# Demo: 移動アニメーション
|
230
|
-
yield from balloon.move(x=200, y=200, duration=3)
|
231
|
-
|
232
|
-
## 3)
|
233
|
-
balloon("Final update!")
|
234
|
-
|
235
|
-
yield from balloon.resize(width=400, height=400)
|
236
|
-
|
237
|
-
yield 3 # wait 3 sec
|
238
|
-
|
239
|
-
# Demo: フェードアウト
|
240
|
-
yield from balloon.fade(alpha=0, duration=3)
|
241
240
|
|
242
241
|
# NOTE: gen_timer ジェネレーターをtkのタイマーで実行する
|
243
242
|
# done=root.quit ジェネレーター完了後に終了
|
243
|
+
balloon = BalloonApp(root)
|
244
|
-
gen_timer(root,
|
244
|
+
gen_timer(root, timeline(balloon), done=root.quit)
|
245
245
|
|
246
246
|
# イベントループはGUIプログラムでは必須
|
247
247
|
root.mainloop()
|