Catching key press events while model wx.MessageDialog(...) is shown?
| Newsgroups | gmane.comp.python.wxpython |
|---|---|
| Message-ID | <[email protected]> |
I have a program that runs a long task in a background thread, and shows a modal wx.MessageDialog(...) in the foreground with a "Stop" button to stop the background thread. The long task is a sequence of work cycles, and the "Stop" button stops the sequence after completing the currently running cycle. So far, all is good (as in the attached example code). I would like to add a mechanism that allows stopping the background thread immediately (without waiting to complete the current cycle) by pressing a key or key combination on the keyboard. For example, pressing the 'K' key on the keyboard should trigger a call to worker_thread.kill() in the attached example code. What would be a good appraoch to make this work? Is there a way to hook into the event loop of the wx.MessageDialog(...) to check for key press events? Of is there another way to check for key presses? -- You received this message because you are subscribed to the Google Groups "wxPython-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/wxpython-users/7eaaf026-4c98-4389-8c2a-cd2d6b1f8c6en%40googlegroups.com.
longtask.py
(text/x-python, 1.7 KB)
import time
from threading import *
import wx
class worker_thread(Thread):
def __init__(self, notify_window):
Thread.__init__(self)
self._notify_window = notify_window
self._want_abort = False
self._want_kill = False
self.start()
def run(self):
num_cycles = 0
while not self._want_abort:
wx.CallAfter(self._notify_window.log_result,num_cycles)
for i in range(50):
time.sleep(0.1)
if self._want_kill:
self._want_abort = True
break
num_cycles += 1
wx.CallAfter(self._notify_window.log_done)
def abort(self):
self._want_abort = True
def kill(self):
self._want_kill = True
class my_frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent=None, title='Main Window', size=(500,300))
self.status_text = wx.StaticText(self, -1, 'Startin up...', pos=(100,100))
self.Show(True)
self.dialog = wx.MessageDialog(self, 'Stop after completing current work cycle?', 'Running cycles...', wx.OK)
self.dialog.SetOKLabel('Stop')
def log_result(self, data):
self.status_text.SetLabel('Working! Number of completed cycles: %s' % data)
def log_abort(self):
self.status_text.SetLabel('User wants to abort work. Finishing the current work cycle...')
def log_done(self):
self.status_text.SetLabel('Finished working. You can close this window now.')
# Main program:
# set up App and main frame:
app = wx.App(False)
frame = my_frame()
# set up long-running taks:
work = worker_thread(frame)
# show modal MessageDialog to abort the work cleanly:
frame.dialog.ShowModal()
# Tell thread to stop running after completing the current cycle:
work.abort()
# Log to my_frame
frame.log_abort()
# do whatever the app is supposed to do after the long-running task:
app.MainLoop()