Я работаю над простым GUI, но я застрял. Это основной поток:
- Показать текст
text
и:
- сэкономить время в
time_pressed
- запустите
progressbar
и обновляйте его, пока не истечет time_notallow
.
- Если пользователь нажимает
<Next>
, посмотрите, прошли ли секунды, указанные в time_notallow
,
и если нет, не разрешать отображение следующего text
.
По сути, я хочу запретить пользователям вызывать метод привязки к клавише <Right>
до тех пор, пока не пройдет time_notallow
, и показать индикатор выполнения, информирующий их о том, как долго им придется ждать. Так как я использую bind
, например ...
self.master.bind('<Right>', self.text_next)
... у меня нет .after()
, как в виджетах.
Что я пробовал
master.after()
для установки bind
на None
и после time_notallow
на bind
на self.text_next
, но это не сработало.
- Создан
thread
, который зацикливается на while True
, чтобы постоянно проверять, передан ли time_notallow
или нет, но приложение вылетает.
Любая помощь приветствуется.
Редактировать: решение. Использование lambda()
в .after
для подсчета секунд (спасибо Брайану Оукли)
"""
Stripped-down version to figue out time/event/threading stuff.
What this has to do:
1. Show the window and some text.
2. User presses Next arrow and new text shows. Paint the label red.
3. Prevent user form pressing again (unbind all keys), until 2 seconds passed
(time_wait).
4. Make notice of passed time and after 2 seconds bind the keys again and
paint the label green.
5. Loop the steps 2-4.
"""
import sys
import tkinter as tk
from tkinter import W, E, S, N
class Test(tk.Frame):
def __init__(self, master=None):
"""Draw the GUI"""
tk.Frame.__init__(self, master)
self.draw_widgets()
self.grid()
self.time_wait = 2
self.locked = False
self.bind_keys()
self.counter = 0
def draw_widgets(self):
"""Draw all the widgets on the frame."""
text = 'Just a sample sentence.'
#Label with the sentence
self.lbl_text = tk.Label(self, anchor="center", relief='groove')
self.lbl_text['text'] = text
self.lbl_text['font'] = ('Helvetica', 27)
self.lbl_text.grid(column=0, row=0, sticky=W+E+S+N)
self.lbl_note = tk.Label(self, anchor="center", relief='groove',
bg='green')
self.lbl_note.grid(column=0, row=1, sticky=W+E+S+N)
def text_next(self, event):
"""Get next text"""
if not self.locked:
self.counter += 1
self.lbl_text['text'] = 'The text number %s!' % self.counter
self.bind_tonone()
self.lock(self.time_wait)
def text_previous(self, event):
"""Get previous text"""
if not self.locked:
self.counter -= 1
self.lbl_text['text'] = 'The text number %s!' % self.counter
self.bind_tonone()
self.lock(self.time_wait)
def bind_keys(self):
"""Bind the keys"""
self.master.bind('<Left>', self.text_previous)
self.master.bind('<Right>', self.text_next)
self.master.bind('<Escape>', self.exit)
self.lbl_note['bg'] = 'green'
def bind_tonone(self):
"""Unbind the keys"""
self.master.bind('<Left>', None)
self.master.bind('<Right>', None)
self.master.bind('<Escape>', None)
self.lbl_note['bg'] = 'red'
def lock(self, n):
if n == 0:
self.locked = False
self.lbl_note['text'] = ''
self.lbl_note['bg'] = 'green'
else:
self.locked = True
self.lbl_note['text'] = 'Locked for %s more seconds' % n
self.lbl_note.after(1000, lambda n = n - 1: self.lock(n))
def exit(self, event):
"""Exit the program."""
sys.exit()
def start():
"""Start the gui part."""
root = tk.Tk()
app = Test(master=root)
app.mainloop()
if __name__ == '__main__':
start()