2013-01-16 75 views
1

我工作的一所學校項目,開發蟒蛇平臺定製的媒體播放器。問題是當我使用time.sleep(持續時間)時,它會阻止我的GUI的主循環阻止它更新。我諮詢了我的主管,被告知使用多線程,但我不知道如何使用線程。有人會告訴我如何在下面的場景中實現線程嗎?如何使用wxPython的線程,以防止阻塞主循環


代碼:

def load_playlist(self, event): 
    playlist = ["D:\Videos\test1.mp4", "D:\Videos\test2.avi"] 
    for path in playlist: 
     #calculate each media file duration 
     ffmpeg_command = ['C:\\MPlayer-rtm-svn-31170\\ffmpeg.exe', '-i' , path] 

     pipe = subprocess.Popen(ffmpeg_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
     results = pipe.communicate() 

     #Regular expression to get the duration 
     length_regexp = 'Duration: (\d{2}):(\d{2}):(\d{2})\.\d+,' 
     re_length = re.compile(length_regexp) 

     # find the matches using the regexp that to compare with the buffer/string 
     matches = re_length.search(str(results)) 
     #print matches 

     hour = matches.group(1) 
     minute = matches.group(2) 
     second = matches.group(3) 

     #Converting to second 
     hour_to_second = int(hour) * 60 * 60 
     minute_to_second = int(minute) * 60 
     second_to_second = int(second) 

     num_second = hour_to_second + minute_to_second + second_to_second 
     print num_second 

     #Play the media file 
     trackPath = '"%s"' % path.replace("\\", "/") 
     self.mplayer.Loadfile(trackPath) 

     #Sleep for the duration of second(s) for the video before jumping to another video 
     time.sleep(num_second) #THIS IS THE PROBLEM# 
+0

難道邁克的或我的回答解決問題了嗎?如果是這樣,請接受/ upvote以表示您對我們時間的讚賞。 – bouke

回答

3

你將開始一個新的線程,就像任何其他的多線程例子:

from threading import Thread 

# in caller code, start a new thread 
Thread(target=load_playlist).start() 

然而,你必須確保調用寬x必須處理線程間通信。你不能從這個新線程調用wx-code。它會段錯誤。因此,使用wx.CallAfter

# in load_playlist, you have to synchronize your wx calls 
wx.CallAfter(self.mplayer.Loadfile, trackPath) 
6

你可能會想看看在wxPython的維基其中有使用線程,隊列和其他有趣的事情的幾個例子:

我也寫了關於這個問題的教程在這裏:http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

要記住的主要是當你使用線程時,你不能直接調用你的wx方法。 myWidget.SetValue等)。相反,你需要使用的wxPython的線程安全的方法之一:wx.CallAfter,wx.CallLater或wx.PostEvent