Отклонить события во время выполнения функции в TKinter - PullRequest
0 голосов
/ 04 октября 2018

У меня есть приложение TKinter (Python), которое реагирует на нажатия кнопок и ввод с клавиатуры.Однако возможно, что функция, которая вызывается после одного из этих событий, может занять некоторое время для выполнения.Я хотел бы, чтобы графический интерфейс отклонял все пользовательские данные во время выполнения функции.[РЕДАКТИРОВАТЬ: просто хочу уточнить: весь пользовательский ввод относится ко всем без исключения кнопкам / привязкам клавиш, которые существуют в приложении - я не просто пытаюсь отклонить событие от определенной кнопки.]

Вот очень простой пример, показывающий, что TKinter в настоящее время добавляет события в очередь, которая выполняется после обработки каждого события.При каждом нажатии кнопки к тексту кнопки добавляется ноль.Однако, если кнопка нажата, когда текст читает 00, выполнение функции занимает некоторое время (я вставил self.after (3000)), и если кнопка нажата, когда эта функция выполняется, то каждый изэти прессы будут регистрироваться.Поэтому, если я нажму кнопку 5 раз в течение 3 секунд, в течение которых она «застопорилась», то каждый из этих щелчков регистрируется, и в итоге я вижу 0000000 на кнопке.

import tkinter as tk

# To demonstrate that keystrokes/button clicks do register while a function is executing (and then subsequently fire)
class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        # Build the app
        self.text = tk.StringVar()
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        self.btn = tk.Button(self, textvariable=self.text, command=self.DoSomething, padx=30, pady=30)
        self.btn.grid(row=0, column=0)
        self.text.set('0')

    def DoSomething(self):
        # self.RejectEventsWhileThisFuncExecutes()
        old_msg = self.text.get()
        if old_msg == '00':
            self.after(3000)
        self.text.set(old_msg + '0')
        # self.BeginAcceptingEventsAgain()

root = tk.Tk()
app = Application(master=root)
app.mainloop()

В основномто, что я хотел бы, это, может быть, что-то, что я могу вызвать в DoSomething() в начале и конце функции, скажем self.RejectEventsWhileThisFuncExecutes() и self.BeginAcceptingEventsAgain(), чтобы убедиться, что во время выполнения функции клики не зарегистрированы.

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Обычной стратегией является создание невидимого виджета (например, кадра 1x1 в углу окна) и выполнение захвата (т. Е. Вызова grab_set) для этого виджета.Это приводит к тому, что все события направляются в этот виджет.Пока в этом окне нет привязок, общий эффект заключается в том, что события игнорируются.Вам просто нужно очистить очередь событий (вызвать метод update) перед удалением захвата.

0 голосов
/ 04 октября 2018

Вы можете удалить команду с кнопки в начале DoSomething:

self.btn.config(command=lambda: None)

, а затем сбросить ее в конце.Просто убедитесь, что update обработал все события в очереди перед повторной привязкой:

self.update()
self.btn.config(command=self.DoSomething)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...