]>
Commit | Line | Data |
---|---|---|
be05b434 RD |
1 | import wx |
2 | import threading | |
3 | import random | |
4 | ||
5 | class WorkerThread(threading.Thread): | |
6 | """ | |
7 | This just simulates some long-running task that periodically sends | |
8 | a message to the GUI thread. | |
9 | """ | |
10 | def __init__(self, threadNum, window): | |
11 | threading.Thread.__init__(self) | |
12 | self.threadNum = threadNum | |
13 | self.window = window | |
14 | self.timeToQuit = threading.Event() | |
15 | self.timeToQuit.clear() | |
16 | self.messageCount = random.randint(10,20) | |
17 | self.messageDelay = 0.1 + 2.0 * random.random() | |
18 | ||
19 | def stop(self): | |
20 | self.timeToQuit.set() | |
21 | ||
22 | def run(self): | |
23 | msg = "Thread %d iterating %d times with a delay of %1.4f\n" \ | |
24 | % (self.threadNum, self.messageCount, self.messageDelay) | |
25 | wx.CallAfter(self.window.LogMessage, msg) | |
26 | ||
27 | for i in range(1, self.messageCount+1): | |
28 | self.timeToQuit.wait(self.messageDelay) | |
29 | if self.timeToQuit.isSet(): | |
30 | break | |
31 | msg = "Message %d from thread %d\n" % (i, self.threadNum) | |
32 | wx.CallAfter(self.window.LogMessage, msg) | |
33 | else: | |
34 | wx.CallAfter(self.window.ThreadFinished, self) | |
35 | ||
36 | ||
37 | ||
38 | class MyFrame(wx.Frame): | |
39 | def __init__(self): | |
40 | wx.Frame.__init__(self, None, title="Multi-threaded GUI") | |
41 | self.threads = [] | |
42 | self.count = 0 | |
43 | ||
44 | panel = wx.Panel(self) | |
45 | startBtn = wx.Button(panel, -1, "Start a thread") | |
46 | stopBtn = wx.Button(panel, -1, "Stop all threads") | |
47 | self.tc = wx.StaticText(panel, -1, "Worker Threads: 00") | |
48 | self.log = wx.TextCtrl(panel, -1, "", | |
49 | style=wx.TE_RICH|wx.TE_MULTILINE) | |
50 | ||
51 | inner = wx.BoxSizer(wx.HORIZONTAL) | |
52 | inner.Add(startBtn, 0, wx.RIGHT, 15) | |
53 | inner.Add(stopBtn, 0, wx.RIGHT, 15) | |
54 | inner.Add(self.tc, 0, wx.ALIGN_CENTER_VERTICAL) | |
55 | main = wx.BoxSizer(wx.VERTICAL) | |
56 | main.Add(inner, 0, wx.ALL, 5) | |
57 | main.Add(self.log, 1, wx.EXPAND|wx.ALL, 5) | |
58 | panel.SetSizer(main) | |
59 | ||
60 | self.Bind(wx.EVT_BUTTON, self.OnStartButton, startBtn) | |
61 | self.Bind(wx.EVT_BUTTON, self.OnStopButton, stopBtn) | |
62 | self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) | |
63 | ||
64 | self.UpdateCount() | |
65 | ||
66 | def OnStartButton(self, evt): | |
67 | self.count += 1 | |
68 | thread = WorkerThread(self.count, self) | |
69 | self.threads.append(thread) | |
70 | self.UpdateCount() | |
71 | thread.start() | |
72 | ||
73 | def OnStopButton(self, evt): | |
74 | self.StopThreads() | |
75 | self.UpdateCount() | |
76 | ||
77 | def OnCloseWindow(self, evt): | |
78 | self.StopThreads() | |
79 | self.Destroy() | |
80 | ||
81 | def StopThreads(self): | |
82 | while self.threads: | |
83 | thread = self.threads[0] | |
84 | thread.stop() | |
85 | self.threads.remove(thread) | |
86 | ||
87 | def UpdateCount(self): | |
88 | self.tc.SetLabel("Worker Threads: %d" % len(self.threads)) | |
89 | ||
90 | def LogMessage(self, msg): | |
91 | self.log.AppendText(msg) | |
92 | ||
93 | def ThreadFinished(self, thread): | |
94 | self.threads.remove(thread) | |
95 | self.UpdateCount() | |
96 | ||
97 | ||
98 | app = wx.PySimpleApp() | |
99 | frm = MyFrame() | |
100 | frm.Show() | |
101 | app.MainLoop() |