実現したいこと
Windows10 環境にて Python ファイルをダブルクリックして生成される Python 端末ウィンドウ(Pythonロゴが端末の前にあるアイコンの端末)の閉じるボタンイベントをキャッチし、即時終了したいです。
環境
- Windows 10 21H2 19044, 1620
- Python 3.9.5 (embeddable python)
発生している問題
Python 端末の閉じるボタンから閉じると固まってしまいます。
GUI は、Python から multiprocessing
にて matplotlib
のアニメーションウィンドウを開き、2窓が同時並行して動く構成になっています。
また、バックグラウンド用にもう1プロセス multiprocessing
で動かしています。
matplotlib
の閉じるイベントはキャッチでき、また Pythonウィンドウも KeyboardInterrupt
もキャッチできているため、ウィンドウに合わせて Ctrl+C を押下したり、matplotlib
の閉じるボタンでは即時終了します。
発生している問題・エラーメッセージ
以下のメッセージが発生しているところを捉えました。
出るかどうかはまちまちです。出ないときはすぐに終了します。
閉じるボタンを押した時点で Windows の画面としては見えなくなるようで
スクショできませんでしたが、カメラで撮ることができました。
Python3
1QObject::~QObject: Timers cannot be stopped from another thread
ソースコード
Python
1import time 2from collections import deque 3from ctypes import * 4from multiprocessing import Array, Process, Queue, freeze_support 5 6import _queue 7import matplotlib.pyplot as plt 8import numpy as np 9 10N = 100 11Q_TIMEOUT = 1 12 13def sampling(sig, q): 14 i = 0 15 16 while True: 17 if not sig.empty(): 18 break 19 20 x = np.linspace(i, i + 2.0 * np.pi, N) 21 y = np.sin(x) 22 23 q.put(y) 24 25 i += 0.001 26 27 28def on_close(event, sig): 29 sig.put(True) 30 31 32def viewer(sig, data_array): 33 plt.ion() 34 35 fig = plt.figure() 36 fig.canvas.mpl_connect( 37 'close_event', lambda event: on_close(event, sig)) 38 39 n = np.linspace(-N, 0, N) 40 y_init = np.ones(N) 41 42 ax = fig.add_subplot(111,) 43 line, = ax.plot(n, y_init,) 44 45 ax.set_ylim([-1.2, 1.2]) 46 47 while True: 48 if not sig.empty(): 49 break 50 51 y = np.array(data_array[0]) 52 53 line.set_ydata(y) 54 55 fig.canvas.blit(ax.bbox) 56 fig.canvas.flush_events() 57 58 59def main(): 60 freeze_support() 61 62 sig = Queue() 63 q = Queue() 64 65 sampler = Process( 66 target=sampling, 67 args=(sig, q,), 68 ) 69 sampler.start() 70 71 data_array = [Array(c_double, range(N))] 72 display = Process( 73 target=viewer, 74 args=(sig, data_array,), 75 ) 76 display.start() 77 78 try: 79 while sampler.is_alive() and display.is_alive(): 80 if not sig.empty(): 81 break 82 83 y = q.get(timeout=Q_TIMEOUT) 84 data_array[0][:] = y 85 86 except KeyboardInterrupt: 87 sig.put(True) 88 89 except _queue.Empty: 90 sig.put(True) 91 92 sig.put(True) 93 display.join() 94 sampler.join() 95 96 97if __name__ == '__main__': 98 main() 99
試したこと
.pyw にすると見えなくなりますが、同時に端末で数値を確認できなくなるためやりたくありません。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。