]>
git.saurik.com Git - wxWidgets.git/blob - 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") ]
80 EVT_ERASE_BACKGROUND(self
, self
.OnEraseBackground
)
81 EVT_PAINT(self
, self
.OnPaint
)
84 def SetValue(self
, index
, value
):
85 assert index
< len(self
.values
)
86 cur
= self
.values
[index
]
87 self
.values
[index
:index
+1] = [(cur
[0], value
)]
90 def SetFont(self
, font
):
91 wxWindow
.SetFont(self
, font
)
93 for label
, val
in self
.values
:
94 w
,h
= self
.GetTextExtent(label
)
97 self
.linePos
= wmax
+ 10
101 def Draw(self
, dc
, size
):
102 dc
.SetFont(self
.font
)
103 dc
.SetTextForeground(wxBLUE
)
104 dc
.SetBackground(wxBrush(self
.GetBackgroundColour()))
106 dc
.SetPen(wxPen(wxBLACK
, 3, wxSOLID
))
107 dc
.DrawLine(self
.linePos
, 0, self
.linePos
, size
.height
-10)
109 bh
= ypos
= self
.barHeight
110 for x
in range(len(self
.values
)):
111 label
, val
= self
.values
[x
]
112 dc
.DrawText(label
, 5, ypos
)
115 color
= self
.colors
[ x
% len(self
.colors
) ]
116 dc
.SetPen(wxPen(color
))
117 dc
.SetBrush(wxBrush(color
))
118 dc
.DrawRectangle(self
.linePos
+3, ypos
, val
, bh
)
121 if ypos
> size
.height
-10:
125 def OnPaint(self
, evt
):
126 size
= self
.GetSize()
127 bmp
= wxEmptyBitmap(size
.width
, size
.height
)
132 wdc
= wxPaintDC(self
)
134 wdc
.Blit(0,0, size
.width
, size
.height
, dc
, 0,0)
137 dc
.SelectObject(wxNullBitmap
)
140 def OnEraseBackground(self
, evt
):
146 #----------------------------------------------------------------------
148 class TestFrame(wxFrame
):
149 def __init__(self
, parent
, log
):
150 wxFrame
.__init
__(self
, parent
, -1, "Thread Test", size
=(450,300))
153 #self.CenterOnParent()
155 panel
= wxPanel(self
, -1)
156 panel
.SetFont(wxFont(10, wxSWISS
, wxNORMAL
, wxBOLD
))
157 wxStaticText(panel
, -1,
158 "This demo shows multiple threads interacting with this\n"
159 "window by sending events to it.", wxPoint(5,5))
162 self
.graph
= GraphWindow(self
, ['Zero', 'One', 'Two', 'Three', 'Four',
163 'Five', 'Six', 'Seven'])
165 sizer
= wxBoxSizer(wxVERTICAL
)
166 sizer
.Add(panel
, 0, wxEXPAND
)
167 sizer
.Add(self
.graph
, 1, wxEXPAND
)
170 self
.SetAutoLayout(true
)
172 #self.graph.SetValue(0, 25)
173 #self.graph.SetValue(1, 50)
174 #self.graph.SetValue(2, 75)
175 #self.graph.SetValue(3, 100)
177 EVT_UPDATE_BARGRAPH(self
, self
.OnUpdate
)
179 self
.threads
.append(CalcBarThread(self
, 0, 50))
180 self
.threads
.append(CalcBarThread(self
, 1, 75))
181 self
.threads
.append(CalcBarThread(self
, 2, 100))
182 self
.threads
.append(CalcBarThread(self
, 3, 150))
183 self
.threads
.append(CalcBarThread(self
, 4, 225))
184 self
.threads
.append(CalcBarThread(self
, 5, 300))
185 self
.threads
.append(CalcBarThread(self
, 6, 250))
186 self
.threads
.append(CalcBarThread(self
, 7, 175))
188 for t
in self
.threads
:
191 EVT_CLOSE(self
, self
.OnCloseWindow
)
194 def OnUpdate(self
, evt
):
195 self
.graph
.SetValue(evt
.barNum
, evt
.value
)
196 self
.graph
.Refresh(false
)
199 def OnCloseWindow(self
, evt
):
200 busy
= wxBusyInfo("One moment please, waiting for threads to die...")
201 for t
in self
.threads
:
206 for t
in self
.threads
:
207 running
= running
+ t
.IsRunning()
213 #----------------------------------------------------------------------
215 def runTest(frame
, nb
, log
):
216 win
= TestFrame(frame
, log
)
221 #----------------------------------------------------------------------
227 The main issue with multi-threaded GUI programming is the thread safty
228 of the GUI itself. On most platforms the GUI is not thread safe and
229 so any cross platform GUI Toolkit and applications written with it
230 need to take that into account.
232 The solution is to only allow interaction with the GUI from a single
233 thread, but this often severly limits what can be done in an
234 application and makes it difficult to use additional threads at all.
236 Since wxPython already makes extensive use of event handlers, it is a
237 logical extension to allow events to be sent to GUI objects from
238 alternate threads. A function called wxPostEvent allows you to do
239 this. It accepts an event and an event handler (window) and instead
240 of sending the event immediately in the current context like
241 ProcessEvent does, it processes it later from the context of the GUI