]>
git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/demo/Threads.py
2 from wxPython
.wx
import *
6 from whrandom
import random
8 #----------------------------------------------------------------------
10 wxEVT_UPDATE_BARGRAPH
= 25015
12 def EVT_UPDATE_BARGRAPH(win
, func
):
13 win
.Connect(-1, -1, wxEVT_UPDATE_BARGRAPH
, func
)
16 class UpdateBarEvent(wxPyEvent
):
17 def __init__(self
, barNum
, value
):
18 wxPyEvent
.__init
__(self
)
19 self
.SetEventType(wxEVT_UPDATE_BARGRAPH
)
24 #----------------------------------------------------------------------
27 def __init__(self
, win
, barNum
, val
):
33 self
.keepGoing
= self
.running
= true
34 thread
.start_new_thread(self
.Run
, ())
37 self
.keepGoing
= false
44 evt
= UpdateBarEvent(self
.barNum
, int(self
.val
))
45 wxPostEvent(self
.win
, evt
)
48 sleeptime
= (random() * 2) + 0.5
49 #print self.barNum, 'sleeping for', sleeptime
52 sleeptime
= sleeptime
* 5
54 self
.val
= self
.val
+ sleeptime
56 self
.val
= self
.val
- sleeptime
58 if self
.val
< 0: self
.val
= 0
59 if self
.val
> 300: self
.val
= 300
63 #----------------------------------------------------------------------
66 class GraphWindow(wxWindow
):
67 def __init__(self
, parent
, labels
):
68 wxWindow
.__init
__(self
, parent
, -1)
72 self
.values
.append((label
, 0))
74 self
.font
= wxFont(12, wxSWISS
, wxNORMAL
, wxBOLD
)
75 self
.SetFont(self
.font
)
77 self
.colors
= [ wxRED
, wxGREEN
, wxBLUE
, wxCYAN
,
78 wxNamedColour("Yellow"), wxNamedColor("Navy") ]
81 def SetValue(self
, index
, value
):
82 assert index
< len(self
.values
)
83 cur
= self
.values
[index
]
84 self
.values
[index
:index
+1] = [(cur
[0], value
)]
87 def SetFont(self
, font
):
88 wxWindow
.SetFont(self
, font
)
90 for label
, val
in self
.values
:
91 w
,h
= self
.GetTextExtent(label
)
94 self
.linePos
= wmax
+ 10
98 def Draw(self
, dc
, size
):
100 dc
.SetTextForeground(wxBLUE
)
101 dc
.SetBackground(wxBrush(self
.GetBackgroundColour()))
103 dc
.SetPen(wxPen(wxBLACK
, 3, wxSOLID
))
104 dc
.DrawLine(self
.linePos
, 0, self
.linePos
, size
.height
-10)
106 bh
= ypos
= self
.barHeight
107 for x
in range(len(self
.values
)):
108 label
, val
= self
.values
[x
]
109 dc
.DrawText(label
, 5, ypos
)
112 color
= self
.colors
[ x
% len(self
.colors
) ]
113 dc
.SetPen(wxPen(color
))
114 dc
.SetBrush(wxBrush(color
))
115 dc
.DrawRectangle(self
.linePos
+3, ypos
, val
, bh
)
118 if ypos
> size
.height
-10:
122 def OnPaint(self
, evt
):
123 size
= self
.GetSize()
124 bmp
= wxEmptyBitmap(size
.width
, size
.height
)
129 wdc
= wxPaintDC(self
)
131 wdc
.Blit(0,0, size
.width
, size
.height
, dc
, 0,0)
134 dc
.SelectObject(wxNullBitmap
)
137 def OnEraseBackground(self
, evt
):
143 #----------------------------------------------------------------------
145 class TestFrame(wxFrame
):
146 def __init__(self
, parent
, log
):
147 wxFrame
.__init
__(self
, parent
, -1, "Thread Test", size
=(450,300))
150 #self.CenterOnParent()
152 panel
= wxPanel(self
, -1)
153 panel
.SetFont(wxFont(10, wxSWISS
, wxNORMAL
, wxBOLD
))
154 wxStaticText(panel
, -1,
155 "This demo shows multiple threads interacting with this\n"
156 "window by sending events to it.", wxPoint(5,5))
159 self
.graph
= GraphWindow(self
, ['Zero', 'One', 'Two', 'Three', 'Four',
160 'Five', 'Six', 'Seven'])
162 sizer
= wxBoxSizer(wxVERTICAL
)
163 sizer
.Add(panel
, 0, wxEXPAND
)
164 sizer
.Add(self
.graph
, 1, wxEXPAND
)
167 self
.SetAutoLayout(true
)
169 #self.graph.SetValue(0, 25)
170 #self.graph.SetValue(1, 50)
171 #self.graph.SetValue(2, 75)
172 #self.graph.SetValue(3, 100)
174 EVT_UPDATE_BARGRAPH(self
, self
.OnUpdate
)
176 self
.threads
.append(CalcBarThread(self
, 0, 50))
177 self
.threads
.append(CalcBarThread(self
, 1, 75))
178 self
.threads
.append(CalcBarThread(self
, 2, 100))
179 self
.threads
.append(CalcBarThread(self
, 3, 150))
180 self
.threads
.append(CalcBarThread(self
, 4, 225))
181 self
.threads
.append(CalcBarThread(self
, 5, 300))
182 self
.threads
.append(CalcBarThread(self
, 6, 250))
183 self
.threads
.append(CalcBarThread(self
, 7, 175))
185 for t
in self
.threads
:
190 def OnUpdate(self
, evt
):
191 self
.graph
.SetValue(evt
.barNum
, evt
.value
)
192 self
.graph
.Refresh(false
)
195 def OnCloseWindow(self
, evt
):
196 busy
= wxBusyInfo("One moment please, waiting for threads to die...")
197 for t
in self
.threads
:
202 for t
in self
.threads
:
203 running
= running
+ t
.IsRunning()
209 #----------------------------------------------------------------------
211 def runTest(frame
, nb
, log
):
212 win
= TestFrame(frame
, log
)
217 #----------------------------------------------------------------------
223 The main issue with multi-threaded GUI programming is the thread safty
224 of the GUI itself. On most platforms the GUI is not thread safe and
225 so any cross platform GUI Toolkit and applications written with it
226 need to take that into account.
228 The solution is to only allow interaction with the GUI from a single
229 thread, but this often severly limits what can be done in an
230 application and makes it difficult to use additional threads at all.
232 Since wxPython already makes extensive use of event handlers, it is a
233 logical extension to allow events to be sent to GUI objects from
234 alternate threads. A function called wxPostEvent allows you to do
235 this. It accepts an event and an event handler (window) and instead
236 of sending the event immediately in the current context like
237 ProcessEvent does, it processes it later from the context of the GUI