Tkinter主循环阻塞效果

时间:2017-03-20 16:04:02

标签: python loops tkinter

我有一个主要的tkinter窗口,用户可以选择一些文件,标记他的选项等等。在按下“运行”按钮时,应该发生以下三件事:

  • 主窗口消失
  • 后台procces开始运行WHILE
  • 出现一个新窗口并开始打印有关正在运行的过程的信息(在下面的例子中,例如,b是3,b是5,b是10等等。

有没有办法在不使用2个线程的情况下做到这一点?(如果是的话,我怎么试过但我无法弄清楚如何结束进程)一个用于GUI,一个用于进程。据我所知,tkinter mainloop具有阻塞效果。 任何建议都非常感谢。 下一个代码应该是揭示 - 每个窗口都有一个类。

import tkinter as Tk
import time

class Mainframe(object):


    def __init__(self,parent):
        self.root=parent
        self.root.title("Main frame")
        self.frame=Tk.Frame(parent)
        self.frame.pack()

        btn=Tk.Button(self.frame,text="Run momma",command=self.RunButton)
        btn.pack()

     def Secondwindow(self):

        self.root.destroy()
        newWindow=Tk.Tk()
        window=Secondframe(newWindow)


    def process(self):

        b=0
        for a in range(0,20):
            b=a
            print (b)
            time.sleep(0.2)

    def RunButton(self):

        self.Secondwindow()
        self.process()


class Secondframe(object):

    def __init__(self,parent):
        self.root=parent
        self.root.title("Main frame")
        self.frame=Tk.Frame(parent)
        self.frame.pack()
        self.root.geometry("400x300")
        self.root.title("otherFrame")

if __name__=="__main__":

    root=Tk.Tk()
    root.geometry("800x600")
    app=Mainframe(root)
    root.mainloop()

1 个答案:

答案 0 :(得分:0)

是的,您可以杀死一个窗口并启动另一个窗口(使用withdrawToplevel,您不应该多次调用Tk()),但为什么要这样做?为什么不直接更新第一个窗口?

import tkinter as tk
import time
import threading

class Mainframe(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.frame = FirstFrame(self)
        self.frame.pack()

    def change(self, frame):
        self.frame.pack_forget() # delete currrent frame
        self.frame = frame(self)
        self.frame.pack() # make new frame

class FirstFrame(tk.Frame):
    def __init__(self, master=None, **kwargs):
        tk.Frame.__init__(self, master, **kwargs)

        master.title("Main frame")
        master.geometry("800x600")

        btn=tk.Button(self,text="Run momma",command=self.RunButton)
        btn.pack()

    def RunButton(self):
        self.master.change(SecondFrame)

class SecondFrame(tk.Frame):
    def __init__(self, master=None, **kwargs):
        tk.Frame.__init__(self, master, **kwargs)
        master.title("otherFrame")
        master.geometry("400x300")
        self.var = tk.StringVar(self)
        lbl = tk.Label(self, textvariable=self.var)
        lbl.pack(anchor='w')
        btn = tk.Button(self, text="go back", command=lambda: master.change(FirstFrame))
        btn.pack()

        t = threading.Thread(target=self.process)
        t.start()


    def process(self):
        b=0
        for a in range(0,20):
            b=a
            print (b)
            self.var.set("Current value is {}".format(b))
            time.sleep(0.2)

if __name__=="__main__":
    app=Mainframe()
    app.mainloop()

注意我仍然使用线程。这是因为当你使用tkinter时你不能进入阻塞循环,因为GUI会锁定。所有长计算都需要集成到tkinter主循环中(通常使用after方法)或它自己的线程。