简体   繁体   中英

Tkinter and multiprocessing

I have a module that calls another module where I initialize a canvas with tkinter and a button. When the user clicks on the button it launches a function from the first module. However this function is long and I don't want to have tkinter frozen until the function is completely executed. It seems that multiprocessing would be the solution but I have some difficulties implementing it.

In the first module:

tkinterModule.initialize(functionFromMainModule)

In the second module:

...
button = Button(master, 
                 text="Launch Function", 
                 command=partial(play, callback))

def play(callback=None):
     if callback is not None:
         callback()

Then in the first module:

def functionFromMainModule():
    ....
    if __name__ == '__main__':
        p = multiprocessing.Process(target=longFunction)
        p.start()

def longFunction():
    ...

But instead of launching longFunction it just reinitializes a new tkinter canvas and doesn't start the function. If I just call the function and don't use multiprocessing the function is called normally (but tkinter is frozen until the end of execution).

Well I suppose, that you are on windows, so your problem is when a new process starts, the Python is pickle -ing all code in your module(or package) (it's because of windows restrictions)

So, when you use a multiprocessing module, you should use a if __name__ == '__main__': statement. Here is the explanation why:

When your code has pickled, it runs in another process, and there all is the same to main process, excluding __name__ variable. This variable can save the code from running the program as the main. Because of this bug, your program clears the canvas and then starts working from scratch.

A possible solution to this problem would be using threads. Python has a module called threading. You can use this module to create threads so that your tkinter app wont freeze. Here is what it looks like.

import threading

def Function(Data):
   print(Data)

thread = threading.Thread(target=Function, args=["Hi"], daemon=True).start()

# daemon simply means that the thread will die once done executing.

We create a thread called thread. The thread will execute the function. Threads divide the program into simultaneously running tasks. Which in other words means that two or more tasks can be ran at a similar time. Threads in the same process use the same memory and resources while a process does not. You can also create threads in classes using the threading module. Just import the threading module and inherit it in a class. For instance,

import threading

class Animal(threading.Thread):
    def __init__(self, v):

        threading.Thread.__init__(self, Variable):  # init for threaded classes
        self.Variable = Variable
        self.Run()
    def Run(self):
        print("I am an animal")


A = Animal("Snake")

A.start()

This is a great thing if you want an object to be acting without slowing down your app and making it crash and freeze.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM