PyOS_InputHook python hook for Qt4. Process pending Qt events and if there's no pending keyboard input, spend a short slice of time (50ms) running the Qt event loop. As a Python ctypes callback can't raise an exception, we catch the KeyboardInterrupt and tem
()
| 76 | # hooks (they both share the got_kbdint flag) |
| 77 | |
| 78 | def inputhook_qt4(): |
| 79 | """PyOS_InputHook python hook for Qt4. |
| 80 | |
| 81 | Process pending Qt events and if there's no pending keyboard |
| 82 | input, spend a short slice of time (50ms) running the Qt event |
| 83 | loop. |
| 84 | |
| 85 | As a Python ctypes callback can't raise an exception, we catch |
| 86 | the KeyboardInterrupt and temporarily deactivate the hook, |
| 87 | which will let a *second* CTRL+C be processed normally and go |
| 88 | back to a clean prompt line. |
| 89 | """ |
| 90 | try: |
| 91 | allow_CTRL_C() |
| 92 | app = QtCore.QCoreApplication.instance() |
| 93 | if not app: # shouldn't happen, but safer if it happens anyway... |
| 94 | return 0 |
| 95 | app.processEvents(QtCore.QEventLoop.AllEvents, 300) |
| 96 | if not stdin_ready(): |
| 97 | # Generally a program would run QCoreApplication::exec() |
| 98 | # from main() to enter and process the Qt event loop until |
| 99 | # quit() or exit() is called and the program terminates. |
| 100 | # |
| 101 | # For our input hook integration, we need to repeatedly |
| 102 | # enter and process the Qt event loop for only a short |
| 103 | # amount of time (say 50ms) to ensure that Python stays |
| 104 | # responsive to other user inputs. |
| 105 | # |
| 106 | # A naive approach would be to repeatedly call |
| 107 | # QCoreApplication::exec(), using a timer to quit after a |
| 108 | # short amount of time. Unfortunately, QCoreApplication |
| 109 | # emits an aboutToQuit signal before stopping, which has |
| 110 | # the undesirable effect of closing all modal windows. |
| 111 | # |
| 112 | # To work around this problem, we instead create a |
| 113 | # QEventLoop and call QEventLoop::exec(). Other than |
| 114 | # setting some state variables which do not seem to be |
| 115 | # used anywhere, the only thing QCoreApplication adds is |
| 116 | # the aboutToQuit signal which is precisely what we are |
| 117 | # trying to avoid. |
| 118 | timer = QtCore.QTimer() |
| 119 | event_loop = QtCore.QEventLoop() |
| 120 | timer.timeout.connect(event_loop.quit) |
| 121 | while not stdin_ready(): |
| 122 | timer.start(50) |
| 123 | event_loop.exec_() |
| 124 | timer.stop() |
| 125 | except KeyboardInterrupt: |
| 126 | global got_kbdint, sigint_timer |
| 127 | |
| 128 | ignore_CTRL_C() |
| 129 | got_kbdint = True |
| 130 | mgr.clear_inputhook() |
| 131 | |
| 132 | # This generates a second SIGINT so the user doesn't have to |
| 133 | # press CTRL+C twice to get a clean prompt. |
| 134 | # |
| 135 | # Since we can't catch the resulting KeyboardInterrupt here |
nothing calls this directly
no test coverage detected