调用after命令时,TKINTER窗口冻结

2024-04-19 15:36:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个小的tkinter程序,允许用户从用户输入名称日期,并将其存储到文本文件中。你知道吗

一切正常。但是当之后执行命令时,一切都会冻结2000毫秒,正如我在下面的代码中提到的那样。当执行after命令时,我无法单击任何小部件。你知道吗

我读过同一个问题的解决方案,但没有一个能解决。你知道吗

调用“after”命令后,如何平稳运行脚本?

代码

from Tkinter import *


def submit():
    # Gets executed when submit button is clicked

    label = Label(label_frame, text='SUBMITTED')
    label.grid(row=3, column=0)

    with open('file.txt', 'a') as f:
        get_name = name_entry.get()
        get_date = date_entry.get()

        f.write('{} {}'.format(get_name, get_date))

    root.update()
    root.after(2000, label.grid_forget())

    # Everything gets paused / freezed when it executes after command

root = Tk()
root.geometry('350x200')

frame = Frame()
label_frame = Frame()

# Setting name label and its entry
name_label = Label(frame, text='NAME')
name_entry = Entry(frame, width=30)
name_label.grid(row=0, column=0)
name_entry.grid(row=0, column=1)

# Setting date label and its entry
date_label = Label(frame, text='DATE')
date_entry = Entry(frame, width=30)
date_label.grid(row=1, column=0)
date_entry.grid(row=1, column=1)

# Setting submit button
submit_button = Button(frame, text='ADD', width=15, command=submit)
submit_button.grid(row=2, column=0, columnspan=5)

# Placing frames to window
frame.place(x=50, y=20)
label_frame.place(x=130, y=100)

root.mainloop()

Tags: textnamegetdatecolumnbuttonrootframe
1条回答
网友
1楼 · 发布于 2024-04-19 15:36:49

参见aftereffbot文档的以下摘录:

after(delay_ms, callback=None, *args)

Registers an alarm callback that is called after a given time.

This method registers a callback function that will be called after a given number of milliseconds. Tkinter only guarantees that the callback will not be called earlier than that; if the system is busy, the actual delay may be much longer.

You can also omit the callback. If you do, this method simply waits for the given number of milliseconds, without serving any events (same as time.sleep(delay_ms*0.001)).

delay_ms
Delay, in milliseconds.

callback
The callback. This can be any callable object.

当你打电话的时候

root.after(2000, label.grid_forget())

传递2000作为延迟(毫秒),这很好。还可以传递label.grid_forget()作为回调。然而,label.grid_forget()并不是一个可调用的对象,而是一个函数调用。因此,它将被执行,其返回值将作为回调传递。因为.grid_forget()的返回值是None,所以实际上您正在调用

root.after(2000, None)

在上面的信息中,您可以看到None是回调的默认值,当您省略回调时,它只是等待给定的毫秒数,而不提供任何事件。因为传递None作为回调,所以基本上忽略了回调,所以tkinter冻结了。你知道吗

您可以通过传递函数对象(可调用)作为回调来解决此问题,而不是调用函数:

root.after(2000, label.grid_forget)

相关问题 更多 >