如何在主进程中获取子进程的return值

How to get return value of sub process in main process

我想在用户单击按钮时启动网络服务器。因此我写了下面的代码:

import tkinter as tk
import tkinter.ttk as ttk
from tkinter import messagebox
import time
from multiprocessing import Process


class MainWindow(ttk.Frame):

    def __init__(self, parent):
        self.parent = parent
        ttk.Frame.__init__(self, master=self.parent)
        self.parent.grab_set()
        self.parent.title("Test_Program")
        self.parent.geometry("500x500")
        ttk.Button(self.parent, text="Start Web-Server", command=self.start_webserver).pack()

    def start_webserver(self):
        if __name__ == '__main__':
            loading_screen = LoadingScreen(self)
            result = [0]
            sub_process = Process(target=start_webserver, args=(result,))
            sub_process.start()
            sub_process.join()
            sub_process.terminate()
            loading_screen.destroy()
            if result[0] == 0:
                messagebox.showinfo("Webserver Status", "Webserver is running!")
            else:
                messagebox.showerror("Webserver Status", "Webserver can't be started an Error occured!")


class LoadingScreen(tk.Toplevel):

    def __init__(self, parent):
        self.parent = parent
        tk.Toplevel.__init__(self, master=self.parent)
        self.geometry("200x50")
        self.title("Loading Screen")
        self.transient(self.parent)
        self.grab_set()
        ttk.Label(self, text="Copying data!").pack()
        status_bar = ttk.Progressbar(self, length=180, mode="indeterminate")
        status_bar.start(5)
        status_bar.pack()

    def __del__(self):
        if isinstance(self.parent, tk.Toplevel):
            self.parent.grab_set()


def start_webserver(result):
    time.sleep(2) # This does represent the time thats necessary to start the webserver
    result[0] = 1

def main():
    root = tk.Tk()
    main_window = MainWindow(root)
    main_window.pack()
    root.mainloop()

if __name__ == "__main__":
    main()

如果我点击 "start webserver" 它会因为 time.sleep(2) 而冻结两秒钟并且不会显示任何进度条。之后就完成了。不知道为什么没有进度条显示。我使用名为 "result" 的数组作为参数来获取 start_webserver(结果)的 return 值,从 sub_process 到 main_process。不幸的是,这也不起作用,因为 "result[0]" 的值保持为 0。我不知道该怎么做。使用数组的想法我也在 Whosebug 上找到了。

这是 Link: how to get the return value from a thread in python?

我自己找到了答案。感谢您的帮助 join() 不正确。我用不同的方式完成了它并关闭 "loading_screen" 以及在第二个线程中完成工作后打开消息框。

这是代码:

import tkinter as tk
import tkinter.ttk as ttk
from tkinter import messagebox
import time
from threading import Thread


class MainWindow(ttk.Frame):

    def __init__(self, parent):
        self.parent = parent
        ttk.Frame.__init__(self, master=self.parent)
        self.parent.grab_set()
        self.parent.title("Test_Program")
        self.parent.geometry("200x50")
        ttk.Button(self.parent, text="Start Web-Server", command=self.start_webserver).pack()

    def start_webserver(self):
        if __name__ == '__main__':
            loading_screen = LoadingScreen(self)
            thread = Thread(target=start_webserver, args=(loading_screen, ))
            thread.start()


class LoadingScreen(tk.Toplevel):

    def __init__(self, parent):
        self.parent = parent
        tk.Toplevel.__init__(self, master=self.parent)
        self.geometry("200x50")
        self.title("Loading Screen")
        self.transient(self.parent)
        self.grab_set()
        ttk.Label(self, text="Copying data!").pack()
        status_bar = ttk.Progressbar(self, length=180, mode="indeterminate")
        status_bar.start(2)
        status_bar.pack()

    def __del__(self):
        if isinstance(self.parent, tk.Toplevel):
            self.parent.grab_set()


def start_webserver(widget):
    return_val = do_some_stuff()
    if return_val:
        widget.destroy()
        messagebox.showinfo("Webserver Status", "Webserver is running!")
    else:
        widget.destroy()
        messagebox.showerror("Webserver Status", "Webserver can't be started an Error occured!\n"
                                                 "Please look inside 'Logfiles/logfile' for more details.")


def do_some_stuff():
    time.sleep(2) # This does represent the time thats necessary to start the webserver
    return True


def main():
    root = tk.Tk()
    main_window = MainWindow(root)
    main_window.pack()
    root.mainloop()


if __name__ == "__main__":
    main()