diff --git a/RFG_ADC_dataplotter.py b/RFG_ADC_dataplotter.py index b16ba5f..e626c23 100755 --- a/RFG_ADC_dataplotter.py +++ b/RFG_ADC_dataplotter.py @@ -22,6 +22,7 @@ import argparse import io import os +import signal import sys import threading import time @@ -1732,11 +1733,42 @@ def main(): ) ani = FuncAnimation(fig, update, interval=interval_ms, blit=False) + cleanup_done = False - plt.show() - # Нормальное завершение при закрытии окна - stop_event.set() - reader.join(timeout=1.0) + def _cleanup(): + nonlocal cleanup_done + if cleanup_done: + return + cleanup_done = True + stop_event.set() + reader.join(timeout=1.0) + + def _handle_sigint(_signum, _frame): + _cleanup() + try: + plt.close(fig) + except Exception: + pass + + prev_sigint = signal.getsignal(signal.SIGINT) + try: + fig.canvas.mpl_connect("close_event", lambda _evt: _cleanup()) + except Exception: + pass + try: + signal.signal(signal.SIGINT, _handle_sigint) + except Exception: + prev_sigint = None + + try: + plt.show() + finally: + _cleanup() + if prev_sigint is not None: + try: + signal.signal(signal.SIGINT, prev_sigint) + except Exception: + pass def run_pyqtgraph(args): @@ -1787,6 +1819,10 @@ def run_pyqtgraph(args): app.setApplicationName(str(args.title)) except Exception: pass + try: + app.setQuitOnLastWindowClosed(True) + except Exception: + pass win = pg.GraphicsLayoutWidget(show=True, title=args.title) win.resize(1200, 600) @@ -2279,8 +2315,26 @@ def run_pyqtgraph(args): timer = pg.QtCore.QTimer() timer.timeout.connect(update) timer.start(interval_ms) + sigint_requested = threading.Event() + sigint_timer = pg.QtCore.QTimer() + sigint_timer.setInterval(50) + sigint_timer.timeout.connect(lambda: app.quit() if sigint_requested.is_set() else None) + sigint_timer.start() + cleanup_done = False def on_quit(): + nonlocal cleanup_done + if cleanup_done: + return + cleanup_done = True + try: + timer.stop() + except Exception: + pass + try: + sigint_timer.stop() + except Exception: + pass stop_event.set() reader.join(timeout=1.0) if control_window is not None: @@ -2289,12 +2343,50 @@ def run_pyqtgraph(args): except Exception: pass + def _handle_sigint(_signum, _frame): + sigint_requested.set() + + prev_sigint = signal.getsignal(signal.SIGINT) + try: + signal.signal(signal.SIGINT, _handle_sigint) + except Exception: + prev_sigint = None + + orig_close_event = getattr(win, "closeEvent", None) + + def _close_event(event): + try: + if callable(orig_close_event): + orig_close_event(event) + else: + event.accept() + except Exception: + try: + event.accept() + except Exception: + pass + try: + app.quit() + except Exception: + pass + + try: + win.closeEvent = _close_event # type: ignore[method-assign] + except Exception: + pass + app.aboutToQuit.connect(on_quit) win.show() exec_fn = getattr(app, "exec_", None) or getattr(app, "exec", None) - exec_fn() - # На случай если aboutToQuit не сработал - on_quit() + try: + exec_fn() + finally: + on_quit() + if prev_sigint is not None: + try: + signal.signal(signal.SIGINT, prev_sigint) + except Exception: + pass if __name__ == "__main__":