Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use wxpython threading to prevent blocking main loop

I'm working on a school project to develop a customized media player on python platform. The problem is when i use time.sleep(duration), it block the main loop of my GUI preventing it from updating. I've consulted my supervisor and was told to use multi-threading but i have no idea how to use threading. Would anyone advice me on how to implement threading in my scenario below?


Code:

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#
like image 730
Winson Avatar asked Apr 18 '26 06:04

Winson


2 Answers

You'll probably want to take a look at the wxPython wiki which has several examples of using threads, Queues and other fun things:

  • http://wiki.wxpython.org/LongRunningTasks
  • http://wiki.wxpython.org/Non-Blocking%20Gui

I also wrote a tutorial on the subject here: http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

The main thing to keep in mind is that when you use threads, you cannot call your wx methods directly (i.e. myWidget.SetValue, etc). Instead, you need to use one of the wxPython threadsafe methods: wx.CallAfter, wx.CallLater or wx.PostEvent

like image 63
Mike Driscoll Avatar answered Apr 20 '26 00:04

Mike Driscoll


You would start a new thread like any other multithreading example:

from threading import Thread

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

However, you have to make sure that calls to wx have to deal with inter-thread communication. You cannot just call wx-code from this new thread. It will segfault. So, use wx.CallAfter:

# in load_playlist, you have to synchronize your wx calls
wx.CallAfter(self.mplayer.Loadfile, trackPath)
like image 33
Bouke Avatar answered Apr 20 '26 00:04

Bouke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!