代码之家  ›  专栏  ›  技术社区  ›  Lehtim

如何获取主流程中子流程的返回值

  •  -1
  • Lehtim  · 技术社区  · 7 年前

    如果用户确实单击了按钮,我想启动一个Web服务器。因此,我编写了以下代码:

    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()
    

    如果我点击“启动webserver”,由于时间的原因,它的两秒钟被冻结了。睡眠(2),没有显示进度条。之后就完成了。我不知道为什么没有显示progressbar。我使用了一个名为“result”的数组作为参数,从sub\u进程到main\u进程获取start\u webserver(result)的返回值。不幸的是,这也不起作用,因为“结果[0]”的值保持为0。我不知道该怎么办。使用我在stackoverflow上找到的数组的想法。

    以下是链接: how to get the return value from a thread in python?

    1 回复  |  直到 7 年前
        1
  •  0
  •   Lehtim    7 年前

    我自己找到了答案。谢谢你的帮助join()不正确。在第二个线程中完成工作后,我以不同的方式完成了这项工作,关闭了“loading\u屏幕”,并打开了messagebox。

    这就是代码:

    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()