Окно TKINTER зависает при вызове команды - PullRequest
0 голосов
/ 09 апреля 2019

У меня есть небольшая программа tkinter, которая позволяет пользователю вводить имя и дату от пользователя и сохранять его в текстовом файле.

Все отлично работает. Но когда после выполнения команды , то все зависает на 2000 миллисекунд, как я уже упоминал в коде ниже. Я не могу нажать ни на один виджет, когда после выполнения команды .

Я прочитал решение той же проблемы, но ни один из них не решил.

Как можно выполнить мой сценарий плавно даже после вызова команды "after"?

CODE

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

1 Ответ

1 голос
/ 09 апреля 2019

См. Следующую выдержку из effbot документации по after:

after(delay_ms, callback=None, *args)

Регистрация аварийного обратного вызовакоторый вызывается через определенное время.

Этот метод регистрирует функцию обратного вызова, которая будет вызываться через определенное количество миллисекунд.Tkinter только гарантирует, что обратный вызов не будет вызван раньше, чем это;если система занята, фактическая задержка может быть намного больше.

Вы также можете пропустить обратный вызов.Если вы это сделаете, этот метод просто ожидает указанное количество миллисекунд, не обслуживая какие-либо события (такие же как time.sleep(delay_ms*0.001)).

delay_ms
Задержка, в миллисекундах.

обратный вызов
обратный вызов.Это может быть любой вызываемый объект.

Когда вы вызываете

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...