]>
git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/demo/Threads.py
75a96e786951f9a4d6c2684114310bdd6159b201
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
] #, wxNamedColour("Yellow") ]
80 def SetValue(self
, index
, value
):
81 assert index
< len(self
.values
)
82 cur
= self
.values
[index
]
83 self
.values
[index
:index
+1] = [(cur
[0], value
)]
86 def SetFont(self
, font
):
87 wxWindow
.SetFont(self
, font
)
89 for label
, val
in self
.values
:
90 w
,h
= self
.GetTextExtent(label
)
93 self
.linePos
= wmax
+ 10
97 def OnPaint(self
, evt
):
101 dc
.SetFont(self
.font
)
102 dc
.SetTextForeground(wxBLUE
)
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:
124 #----------------------------------------------------------------------
126 class TestFrame(wxFrame
):
127 def __init__(self
, parent
, log
):
128 wxFrame
.__init
__(self
, parent
, -1, "Thread Test", size
=(450,300))
131 #self.CenterOnParent()
133 panel
= wxPanel(self
, -1)
134 panel
.SetFont(wxFont(10, wxSWISS
, wxNORMAL
, wxBOLD
))
135 wxStaticText(panel
, -1,
136 "This demo shows multiple threads interacting with this\n"
137 "window by sending events to it.", wxPoint(5,5))
140 self
.graph
= GraphWindow(self
, ['Zero', 'One', 'Two', 'Three'])
142 sizer
= wxBoxSizer(wxVERTICAL
)
143 sizer
.Add(panel
, 0, wxEXPAND
)
144 sizer
.Add(self
.graph
, 1, wxEXPAND
)
147 self
.SetAutoLayout(true
)
149 #self.graph.SetValue(0, 25)
150 #self.graph.SetValue(1, 50)
151 #self.graph.SetValue(2, 75)
152 #self.graph.SetValue(3, 100)
154 EVT_UPDATE_BARGRAPH(self
, self
.OnUpdate
)
156 self
.threads
.append(CalcBarThread(self
, 0, 25))
157 self
.threads
.append(CalcBarThread(self
, 1, 50))
158 self
.threads
.append(CalcBarThread(self
, 2, 75))
159 self
.threads
.append(CalcBarThread(self
, 3, 100))
161 for t
in self
.threads
:
166 def OnUpdate(self
, evt
):
167 self
.graph
.SetValue(evt
.barNum
, evt
.value
)
171 def OnCloseWindow(self
, evt
):
172 busy
= wxBusyInfo("One moment please, waiting for threads to die...")
173 for t
in self
.threads
:
178 for t
in self
.threads
:
179 running
= running
+ t
.IsRunning()
185 #----------------------------------------------------------------------
187 def runTest(frame
, nb
, log
):
188 win
= TestFrame(frame
, log
)
193 #----------------------------------------------------------------------
199 The main issue with multi-threaded GUI programming is the thread safty
200 of the GUI itself. On most platforms the GUI is not thread safe and
201 so any cross platform GUI Toolkit and applications written with it
202 need to take that into account.
204 The solution is to only allow interaction with the GUI from a single
205 thread, but this often severly limits what can be done in an
206 application and makes it difficult to use additional threads at all.
208 Since wxPython already makes extensive use of event handlers, it is a
209 logical extension to allow events to be sent to GUI objects from
210 alternate threads. A function called wxPostEvent allows you to do
211 this. It accepts an event and an event handler (window) and instead
212 of sending the event immediately in the current context like
213 ProcessEvent does, it processes it later from the context of the GUI