简体   繁体   English

time.sleep阻止按tkinter.Button

[英]time.sleep blocks pressing tkinter.Button

I am trying to implement an app to show image for 6s and then jump to another page with radio buttons to let them rate their own feeling about the images (give 15s for rating) and then show the next image. 我正在尝试实现一个应用程序,以显示6s的图像,然后跳转到带有单选按钮的另一页,以让他们对图像的感觉进行评分(给15s评分),然后显示下一张图像。 However, for counting down 15s, I used time.sleep() function, which make the program very slow for pressing radiobuttons (but my clicking, the button can still be pressed). 但是,为了倒数15秒,我使用了time.sleep()函数,该函数使按下单选按钮的程序非常慢(但是单击后仍可以按下该按钮)。 I am wondering whether there is a way that the count down will not influence the program but just let the program jump to the next page when time up. 我想知道是否有一种方法,倒数不会影响程序,而只是在时间到时让程序跳到下一页。 Here is my code : 这是我的代码:

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.geometry('1800x970+15+5')
        self.title('Emotion Test')
        # the container is where we'll stack a bunch of frames
        # on top of each other, then the one we want visible
        # will be raised above the others
        container = tk.Frame(self)
        container.pack(side="top", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (StartPage, Show_image, Rate_e, EndPage):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame

            # put all of the pages in the same location;
            # the one on the top of the stacking order
            # will be the one that is visible.
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage")
    def show_frame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self.frames[page_name]
        frame.tkraise()
        frame.execute()


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text=instructions, width=1500, height=700, font=TITLE_FONT)
        label.pack(side="top")
        label.place(x=100, y=40, width=1500, height=700)
        button1 = tk.Button(self, text="Start", height = 5, width = 10,
                            command=lambda: controller.show_frame("Show_image"))
        button1.pack(side="bottom")

    def execute(self):
        current = -1

class EndPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text=instructions, width=1500, height=700,
        font=TITLE_FONT)
        label.pack(side="top")
        label.place(x=100, y=40, width=1500, height=700)

    def execute(self):
        current = -1

class Show_image(tk.Frame):

    def __init__(self, parent, controller):
        global seconds
        tk.Frame.__init__(self, parent)
        self.controller = controller
        global lbPic
        global timer1
        lbPic = tk.Label(self, text='Image System', width=1200, height=900)
        lbPic.place(x=20, y=50, width=1200, height=900)
        lbPic.pack(side="top", fill="both", expand=True)
        timer1 = tk.Label(self, text='timer', width=50, height=10)
        timer1.place(x=1325, y=2, width=50, height=10)
        timer1.pack(side="bottom", fill="both", expand=True)
    def execute(self):
        if (self.changePic(1)):
           for k in range(seconds, 0, -1):
               timer1["text"] = "Time left : " + str(k) + " s"
               self.update()
               time.sleep(1)
           self.controller.show_frame("Rate_e")
        else:
           self.controller.show_frame("EndPage")

    def changePic(self, flag):
        global current

        new = current + flag
        if new<0:
           #tkMessageBox.showerror('', 'last picture')
           return 0
        elif new>=len(pics):
             #tkMessageBox.showerror('', 'last picture')
             return 0
        else:
             #get the next picture
             pic = pics[new]
             im = Image.open(pic)
             w, h = im.size
             if w>1200:
                h = int(h*1200/w)
                w = 1200
             if h>800:
                w = int(w*800/h)
                h = 800
             im = im.resize((w,h))
             im1 = ImageTk.PhotoImage(im)
             lbPic['image'] = im1
             lbPic.image = im1
             current = new
             return 1

class Rate_e(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        global wait
        self.controller = controller
        global lbrate1
        global lbrate2
        global lbrate3
        global timer2
        lbrate1 = tk.Label(self, text='Pleasure', width=1400, height=260)
        lbrate1.place(x=50, y=10, width=1400, height=260)
        lbrate1.pack(side="top", fill="both", expand=True)
        lbrate2 = tk.Label(self, text='Excited', width=1400, height=260)
        lbrate2.place(x=50, y=230, width=1400, height=260)
        lbrate2.pack(side="top", fill="both", expand=True)
        lbrate3 = tk.Label(self, text='Controlled', width=1400, height=260)
        lbrate3.place(x=50, y=650, width=1400, height=260)
        lbrate3.pack(side="top", fill="both", expand=True)
        timer2 = tk.Label(self, text='timer', width=50, height=10)
        timer2.place(x=800, y=850, width=50, height=10)
        timer2.pack(side="bottom", fill="both", expand=True)

        MODES = [
            ("1", 1),
            ("2", 2),
            ("3", 3),
            ("4", 4),
            ("5", 5),
            ("6", 6),
            ("7", 7),
            ("8", 8),
            ("9", 9)
        ]
        global v1
        v1 = tk.StringVar()
        v1.set("score1") # initialize
        xaxis = 0
        for text, mode in MODES:
            b1 = tk.Radiobutton(self, text=text,
                        variable=v1, value=mode)
            b1.config(indicatoron=False,width=10,height=2)
            b1.place(x=140 + xaxis*127, y=240 , width=100, height=30)
            #b.pack(side="left")
            xaxis = xaxis + 1
        global v2
        v2 = tk.StringVar()
        v2.set("score2") # initialize
        xaxis = 0
        for text, mode in MODES:
            b2 = tk.Radiobutton(self, text=text,
                        variable=v2, value=mode)
            b2.config(indicatoron=False,width=10,height=2)
            b2.place(x=140 + xaxis*128, y=510 , width=100, height=30)
            #b.pack(side="left")
            xaxis = xaxis + 1
        global v3
        v3 = tk.StringVar()
        v3.set("score3") # initialize
        xaxis = 0
        for text, mode in MODES:
            b3 = tk.Radiobutton(self, text=text,
                        variable=v3, value=mode)
            b3.config(indicatoron=False,width=10,height=2)
            b3.place(x=140 + xaxis*125, y=800 , width=100, height=30)
            #b.pack(side="left")
            xaxis = xaxis + 1

    def execute(self):
        for k in range(wait, 0, -1):
            timer2["text"] = "Time left : " + str(k) + " s"
            self.update()
            time.sleep(1)
        Pleasure = v1.get()
        Excited = v2.get()
        Control = v3.get()
        print(Pleasure)
        print(Excited)
        print(Control)
        self.controller.show_frame("Show_image")

if __name__ == "__main__":
    suffix = ('.jpg', '.bmp', '.png')
    pics = [image_path + p for p in os.listdir(image_path) if p.endswith(suffix)]
    seconds = 2
    wait = 6
    current = -1
    app = SampleApp()
    app.mainloop()

Using time.sleep() in a tkinter program will make it unresponsive since it keeps the mainloop() from executing and able to respond to events. 使用time.sleep()tkinter ,因为它使该方案将使其反应迟钝mainloop()从执行,并能够对事件做出响应。

To void that use the universal widget method after() . 要使此无效,请使用after()通用小部件方法。

So, in your case use: 因此,在您的情况下使用:

self.after(1000)  # 1000 ms = 1 sec

instead of 代替

time.sleep(1)

Here's some documentation I found about it. 这是我发现的一些文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM