qt qt-for-python pyside pyside2

Source

import signal
 
from PySide2.QtCore import QCoreApplication, QEvent
 
class CoreApplication(QCoreApplication):
    """needed for proper Ctrl-C behavior (see: https://stackoverflow.com/a/11705366/12780516)"""
    def event(self, event: QEvent) -> bool:
        return super().event(event)
 
def main():
    handler = None
 
    def handle_sigint(*args):
        print("handle_sigint")
        global app
        if app is None:
            print("received SIGINT before app was initialized")
            return
        signal.signal(signal.SIGINT, handler)
        app.quit()
 
    handler = signal.signal(signal.SIGINT, handle_sigint)
    global app
    app = CoreApplication()
    app.startTimer(100)
    app.exec_()
 
 
if __name__ == "__main__":
    main()
    print("done")
  • for PySide6 on Windows only!, the only solution that works is to create a custom CoreApplication class which overrides event, catches KeyboardInterrupt in there and then quits the application
from PySide6.QtCore import QCoreApplication, QEvent
 
class CoreApplication(QCoreApplication):
    """needed for proper Ctrl-C behavior (see: https://stackoverflow.com/a/11705366/12780516)."""
 
    def event(self, event: QEvent) -> bool:  # noqa: D102
        try:
            return super().event(event)
        except KeyboardInterrupt:
            # NOTE: this only works in a terminal but not in VSCode's debugger
            self.quit()
            return True
 
 
def main() -> None:
    """
    Main application entry point.
    """
 
    if (qapp := QCoreApplication.instance()) is None:
        import sys
 
        qapp = CoreApplication(sys.argv)
    else:
        # need to use our custom CoreApplication class to handle KeyboardInterrupt
        qapp.__class__ = CoreApplication
 
    qapp.startTimer(100)
 
    qapp.exec()
 
 
if __name__ == "__main__":
    main()