Python Tkinter与多处理

Python Tkinter与多处理,python,tkinter,python-multiprocessing,Python,Tkinter,Python Multiprocessing,我有一个调用另一个模块的模块,在这个模块中,我用tkinter和一个按钮初始化画布。当用户单击按钮时,它将从第一个模块启动一个功能。但是这个函数很长,我不想让tkinter冻结,直到函数完全执行。似乎多处理是解决方案,但我在实现它时遇到了一些困难 在第一个模块中: tkinterModule.initialize(functionFromMainModule) def functionFromMainModule(): .... if __name__ == '__main__

我有一个调用另一个模块的模块,在这个模块中,我用tkinter和一个按钮初始化画布。当用户单击按钮时,它将从第一个模块启动一个功能。但是这个函数很长,我不想让tkinter冻结,直到函数完全执行。似乎多处理是解决方案,但我在实现它时遇到了一些困难

在第一个模块中:

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

def longFunction():
    ...
在第二个模块中:

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

def play(callback=None):
     if callback is not None:
         callback()
然后在第一个模块中:

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

def longFunction():
    ...

但是它没有启动longFunction,只是重新初始化了一个新的tkinter画布,而没有启动该函数。如果我只调用函数而不使用多处理,则函数将正常调用(但tkinter将被冻结,直到执行结束)。

此问题的可能解决方案是使用线程。Python有一个称为线程的模块。您可以使用此模块创建线程,以便tkinter应用程序不会冻结。这是它的样子

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.
我们创建了一个名为thread的线程。线程将执行该函数。线程将程序划分为同时运行的任务。换句话说,这意味着两个或多个任务可以在相同的时间运行。同一进程中的线程使用相同的内存和资源,而进程不使用。还可以使用线程模块在类中创建线程。只需导入线程模块并在类中继承它。比如说,

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()
如果你想让一个对象在运行时不会减慢你的应用程序的速度,也不会让它崩溃和冻结,这是一件很棒的事情

好 我想,您是在windows上,所以您的问题是当一个新进程启动时,Python正在
pickle
-清除模块(或包)中的所有代码(这是因为windows)

因此,当您使用多处理模块时,应该使用
if uuuu name uuuu=='\uuuuu main uuu':
语句。以下是原因说明:


当您的代码被pickle处理后,它会在另一个进程中运行,并且主进程中的所有内容都是相同的,不包括
\uuu name\uuuu
变量。此变量可以将运行程序时的代码保存为主进程。由于此错误,您的程序会清除画布,然后从头开始工作。

所有GUI都应该在一个线程中。其他threads或进程应该只进行计算,并将结果或信息发送到主线程,这将改变GUI。也许可以为您的问题创建最小的工作示例,以便我们可以运行它。也许您应该在
中运行所有代码,如果
名称,而不仅仅是多进程。您在windows上吗?如果是,您应该使用
如果
==“\uuuu main\uuuuuu”语句不是这样做的。唯一不应该做的事情是像您那样调用目标。相反,只允许将可调用参数和附加参数作为args参数或通过functools.partial传递。另外,我很抱歉,您基于类的示例也不起作用。大小写很重要。您需要我将运行ˋRunˋ,但更重要的是启动线程。并调用ˋthread。uu init_uˋ。谢谢你纠正我说的话。我写错了。为什么称它为runDeets。如果我们不能调用目标,那么我们如何执行线程?这是可行的!我只是很惊讶当你在进程:
p=multiprocessing.process(target=longFunction)