Python Forum

Full Version: Multiprocessing in wx Frame
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I create a GUI window by using wx Frame/Panel and make a sample with some dummy code below.
when click on Run button, it will call function_1 with 0 as parameter and get returned result.
function_1 will take 2 minutes to finish but when running, the window will freeze until done.
I'm wondering if possible to run it in anther processor or thread which is different from its parent wx.Frame by using something like multiprocessing or multithreading. so I can still work on the window while function_1 is running. Thanks.

import wx

class Frame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="Multiprocessing", size=(550, 550), pos = (300, 300))
        p = wx.Panel(self)
        runButton = wx.Button(self, label="Run it", pos=(200, 200))
        runButton.Bind(wx.EVT_BUTTON, self.onClick)
    def onClick(self,event):
        print('function_1 will run 2 minutes and return result.')
#       r = function_1(0)
#       function_2(r)
#   def function_1():
#       ......
#       return result
if __name__ == "__main__":
    app = wx.App()
    win = Frame()
    win.CreateStatusBar()
    win.Show()
    app.MainLoop()
I make some changes and test it. It looks like multiprocessing not able to run inside wx Frame. My purpose is after clicking the button, function_1 will be started in a separate process and the control will turn back to wx Frame MainLoop so I can continue to do other things like making changes in the grid, don't need to wait 2 minutes. is it possible? Thanks.

import time
import wx.grid
from multiprocessing import Process

class Frame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="Multiprocessing", size=(600, 500), pos = (300, 300))
        wx.Panel(self)
        self.SetBackgroundColour("Blue")
        grid = wx.grid.Grid(self, size=(400,100), pos=(100,100))
        grid.CreateGrid(3,3)
        for c in range(3): grid.SetColSize(c,100)
        for r in range(3):
            grid.SetRowLabelValue(r,time.strftime('%H:%M:%S'))
            for c in range(3):  grid.SetCellValue(r, c, "R"+str(r)+"/C"+str(c))
        runButton = wx.Button(self, label="Run it", pos=(250, 250))
        runButton.Bind(wx.EVT_BUTTON, self.onClick)
    def onClick(self,event):
##        p = Process(target=self.function_1)
##        p.start()
        self.function_1()
        print('function_1 run 2 minutes and return result.')
    def function_1(self):
        time.sleep(120)
if __name__ == "__main__":
    app = wx.App()
    win = Frame()
    win.CreateStatusBar()
    win.Show()
    app.MainLoop()
Wxpython has own Threadsafe Methods.
  • wx.PostEvent
  • wx.CallAfter
  • wx.CallLater
This is good post about it,and some more usage of long running task here.
There are more link in bottom of that post that address these issue.
Thank you Snippsat. It is really helpful. I add a thread class in my test program posted and seems working great. So I modify my real program. The program has a timer and fire/run the function every 5 minutes. So I create a single thread to run this function. It run ok in first 5-minute period but it crashes in second run. I search Internet and found the following can solve the crash problem. I install dask ok but still get error for import dask. I use python 3.6.1 64bit on Windows 10. Thanks.
import dask
dask.set_options(get=dask.async.get_sync)