用户界面上的按钮挂起

时间:2015-02-12 06:38:59

标签: multithreading user-interface python-2.7 tkinter locking

我在某个网站上发现了类似于我的问题的以下代码。每当我按下用户界面上的按钮时,它就会挂起。请帮我解决这个问题。

import Tkinter
from Tkinter import *
import Tkinter as tk
import time

class simpleapp_tk(Tkinter.Tk):
    def __init__(self,parent):
        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.grid()


        button = Tkinter.Button(self,text=u"Click me !",
                                command=self.OnButtonClick)
        button.grid(column=1,row=0)


        self.grid_columnconfigure(0,weight=1)
        self.resizable(True,False)

    def OnButtonClick(self):
        for i in range(10):
            print 'deep'
            time.sleep(1)

    def OnPressEnter(self,event):
        self.labelVariable.set("You pressed enter !")

if __name__ == "__main__":
    app = simpleapp_tk(None)
    app.title('my application')
    app.mainloop()

1 个答案:

答案 0 :(得分:1)

我相信你是在追求这样的事情:

import Tkinter 
import time

class simpleapp_tk(Tkinter.Tk):
    def __init__(self,parent):
        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.grid()


        button = Tkinter.Button(self,text=u"Click me !",
                                command=self.OnButtonClick)
        button.grid(column=1,row=0)


        self.grid_columnconfigure(0,weight=1)
        self.resizable(True,False)

        self.i = 0; #<- make counter 

    def OnButtonClick(self):            
        print 'deep'
        self.i += 1;
        if self.i==10: return #<1-- stop if we hit 10 iterations
        self.after(1000, self.OnButtonClick) #<- use this


    def OnPressEnter(self,event):
        self.labelVariable.set("You pressed enter !")

if __name__ == "__main__":
    app = simpleapp_tk(None)
    app.title('my application')
    app.mainloop()

请查看标记的更改。基本上,最好使用after方法在给定时间执行某些操作而不是阻止整个tk窗口。因此,如果您想要执行10次某些操作,只需使用一些可以保留计数器的self.i并使用OnButtonClick方法调用self.after

作为替代方案,您可以将循环放入单独的线程中。例如:

import Tkinter 
import time

import threading

class simpleapp_tk(Tkinter.Tk):
    def __init__(self,parent):
        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.grid()


        button = Tkinter.Button(self,text=u"Click me !",
                                command=self.OnButtonClick)
        button.grid(column=1,row=0)


        self.grid_columnconfigure(0,weight=1)
        self.resizable(True,False)

        # define a thread, but dont start it yet.
        # start it when button is pressed.
        self.t = threading.Thread(target=self.do_in_loop)

    def do_in_loop(self):
        # this will be executed in a separate thread.
        for i in range(10):
            print i, 'deep'
            time.sleep(1)

    def OnButtonClick(self):
        # start the thread with the loop 
        # so that it does not block the tk.
        if not self.t.isAlive():
            self.t.start()


    def OnPressEnter(self,event):
        self.labelVariable.set("You pressed enter !")

if __name__ == "__main__":
    app = simpleapp_tk(None)
    app.title('my application')
    app.mainloop()