wxpython in action_wxPython in Action (multi-Thread)--验证有效

http://www.programmershare.com/2059410/

18.6 Creating a multithreaded wxPython application

Most GUI applications, in the the application background long-term implementation of a process without interfering with the interaction of the user with the application of other parts of the good. The mechanism allows spooled usually is to generate a thread and a process executed in the thread and long-term. For wxPython multi-threaded, in this section we have two points to note.

The most important thing is to the GUI operation must take place in the place in which the main loop of the main thread or application. Run the GUI in a separate thread for unpredictable program crashes and debugging is a good idea. For technical reasons, such as many Unix GUI library is not thread-safe, as well as in Microsoft Windows UI objects created the wxPython no design its own events occur in multi-threaded, so we recommend that you do not try to .

The above prohibition includes any project interact with the screen, including in particular wx.Bitmap objects.

WxPython application updates on all of the UI, the background thread only responsible for sending a message to the UI thread, do not care about the GUI update. Fortunately, the wxPython no forced limited to the number of background thread.

In this section, we will focus on several wxPython multi-threaded approach. The most common technique is use wx.CallAfter () function, and for a while we will discuss it. Then, we'll take a look at how to use the the Python queue object to set up a parallel event queue. Finally, we will discuss how to develop a customized solution for multi-threaded.

18.6.1 use the global function wx.CallAfter (and)

Example 18.5 shows an example of a thread, it uses the wxPython the global function wx.CallAfter (), the function is to pass a message to your main thread the easiest way. wx.CallAfter () so that the main thread after the completion of the current event handler, you can call a function on a different thread. Passed to wx.CallAfter () function object is always to be executed in the main thread.

Figure 18.4 shows the results of the multi-threaded window.

Figure 18.4

Example 18.5 shows the code of the generated 18.4

Example 18.5 wx.CallAfter () to pass the message to the main thread, a thread example

# - * - Encoding: UTF-8 - * -

import wx

import threading

import random

class WorkerThread (threading.Thread):

"" "

This just simulates some long-running task that periodically sends

a message to the GUI thread.

"" "

def __ init__ (self threadNum, window):

threading.Thread.__init__ (self)

self.threadNum = threadNum

self.window = window

self.timeToQuit = threading.Event ()

self.timeToQuit.clear ()

self.messageCount = random.randint (10, 20)

self.messageDelay = 0.1 + 2.0 * random.random ()

def stop (self):

self.timeToQuit.set ()

def run (self): # run a thread

msg = "Thread% d iterating% d times with a delay of% 1.4f \ n" \

% (Self.threadNum, self.messageCount, self.messageDelay)

wx.CallAfter (self.window.LogMessage, msg)

for i in range (1, self.messageCount +1):

self.timeToQuit.wait (self.messageDelay)

the if self.timeToQuit.isSet ():

break

msg = "Message% d from thread% d \ n"% (i, self.threadNum)

wx.CallAfter (self.window.LogMessage, msg)

else:

wx.CallAfter (self.window.ThreadFinished, self)

class MyFrame (wx.Frame):

def __ init__ (self):

wx.Frame.__init__ (self, None, title = "Multi-threaded GUI")

The = [self.threads]

self.count = 0

panel = wx.Panel (self)

startBtn = wx.Button (panel, -1, "Start a thread")

stopBtn = wx.Button (panel, -1, "Stop all threads")

self.tc = wx.StaticText (panel, -1, "Worker Threads: 00")

self.log = wx.TextCtrl (panel, -1, "",

style = wx.TE_RICH | wx.TE_MULTILINE)

inner = wx.BoxSizer (wx.HORIZONTAL)

inner.Add (startBtn, 0, wx.RIGHT, 15)

inner.Add (stopBtn, 0, wx.RIGHT, 15)

inner.Add (self.tc, 0, wx.ALIGN_CENTER_VERTICAL)

main = wx.BoxSizer (wx.VERTICAL)

main.Add (inner, 0, wx.ALL, 5)

main.Add (self.log, 1, wx.EXPAND | wx.ALL, 5)

panel.SetSizer (main)

self.Bind (wx.EVT_BUTTON, self.OnStartButton, startBtn)

self.Bind (wx.EVT_BUTTON, self.OnStopButton, stopBtn)

self.Bind (wx.EVT_CLOSE, self.OnCloseWindow)

self.UpdateCount ()

to def OnStartButton (self, evt):

self.count + = 1

thread = WorkerThread (self.count, self) # create a thread

self.threads.append (thread)

self.UpdateCount ()

Thread.start () # start the thread

to def OnStopButton (self, evt):

self.StopThreads ()

self.UpdateCount ()

to def OnCloseWindow (self, evt):

self.StopThreads ()

self.Destroy ()

the def StopThreads (self): # remove the thread from the pool

while self.threads:

The thread = self.threads []

Thread.stop ()

self.threads.remove (thread)

. def updatecount (self):

self.tc.SetLabel ("Worker Threads:% d"% len (self.threads))

def the LogMessage (self, msg): # register a message

self.log.AppendText (msg)

def ThreadFinished (self, thread): # delete the thread

self.threads.remove (thread)

self.UpdateCount ()

the APP = wx.PySimpleApp ()

FRM = MyFrame ()

frm.Show ()

app.MainLoop ()

The above example uses the Python threading module. The above code wx.CallAfter (func, * args) delivery method to the main thread. This will send an event to the main thread, the event is handled in a standard manner, and trigger a call to func (* args). Therefore, and in this case, the thread is called during its life cycle LogMessage (), and before the end of the thread to call ThreadFinished ().

18.6.2 the queue object management thread communication

Despite using CallAfter () is the easiest way of communication of management thread, but it is not the only mechanism.You can use Python's thread-safe queue object to send commands to object to the UI thread. The UI thread should be written in the of wx.EVT_IDLE event handler need to accept commands from the queue.

Essentially, you want to the thread communication set up a parallel event queue. If you use this method, then the worker thread when a command object to the queue if they increase, should call the global function wx.WakeUpIdle () to ensure that there is as much as possible in a free event. This technique is more complex than wx.CallAfter (), but also more flexible. In particular, this mechanism can help you communicate in a background thread, all GUI handling is still on the main thread.

18.6.3 develop your own solutions

You can also make your own thread to create a wxPython event (standard or custom), use the global function wx.PostEvent (window, event) and send it to the UI thread in a specific window. The event is added to a specific window in the pending event queue, and wx.WakeUpIdle is called automatically. The benefits of this road is the event will traverse wxPython event is set, which means you will be free to get many event processing capabilities, the downside is that you have to manage their own all the threads, and wx.CallAfter () event handler function do for you .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值