@__blackjack__: Okay, jetzt funktioniert `after_cancel()` so wie es soll. Danke für die Erklärung.
Die nächste Macke, die ich dem Programm gerne austreiben würde, ist, dass sich das Programm nach einem Klick auf "OK" im Ergebnisfenster (`results_window`) komplett beendet.
Dieser "OK"-Button wird im Programm mit folgendem Code erzeugt:
Code: Alles auswählen
ok_button = Button(results_window, text="OK", padx=10, pady=10, command=results_window.quit)
Nach meinem Verständnis müsste sich beim Aufruf von `results_window.quit` nur das Ergebnisfenster (`results_window`) schließen und nicht das komplette Programm, aber offensichtlich liege ich da etwas falsch. Wie macht man das richtig?
Aktueller Code:
Code: Alles auswählen
from tkinter import Tk, Canvas, Toplevel, Frame, Label, Button, Listbox
from random import choice
import time
from statistics import mean
DESIGNATED_COLOR = "red"
SWITCH_TIME = 1000
class Game:
def __init__(self, main_window):
self.main_window = main_window
self.colors = ["green", "red", "blue", "yellow", "black"]
self.color = None
self.reaction_times = []
self.false_positives = 0
self.color_missed = 0
self.key_too_often_pressed = 0
self.stop_test = False
self.color_locked = False
self.id_value_change_bg_color = 0
def start_game(self):
self.game_window = Toplevel(self.main_window)
self.game_window.attributes("-fullscreen", True)
self.canvas = Canvas(self.game_window,
width=self.game_window.winfo_screenwidth(),
height=self.game_window.winfo_screenheight(),
highlightthickness=0)
self.canvas.pack()
self.change_bg_color()
def change_bg_color(self, color_locked = False):
if self.stop_test:
self.game_window.destroy()
if not self.color_locked and self.color == DESIGNATED_COLOR:
self.color_missed += 1
self.color_locked = color_locked
current_color = self.color
while self.color == current_color:
self.color = choice(self.colors)
self.canvas.config(bg=self.color)
self.start_time = time.monotonic() # Ereignis Timer
self.id_value_change_bg_color = self.game_window.after(SWITCH_TIME, self.change_bg_color)
def key_pressed(self):
if self.color == DESIGNATED_COLOR:
if self.color_locked:
self.key_too_often_pressed += 1
else:
reaction_time = time.monotonic() - self.start_time
self.reaction_times.append(reaction_time)
self.color_locked = True
else:
self.false_positives += 1
def show_results(self, event=None):
self.game_window.after_cancel(self.id_value_change_bg_color)
self.stop_test = True
results_window = Toplevel(self.main_window)
results_frame = Frame(results_window)
results_window.title("Ergebnisse")
if self.reaction_times:
# mean() auf Liste ohne Einträge führt zu einem Fehler
desc_mean_reaction_time = Label(results_frame, text="Gemittelte Reaktionszeit:")
desc_reaction_times = Label(results_frame, text="Reaktionszeit pro richtiger Farbe:")
result_mean_reaction_time = Label(results_frame, text=mean(self.reaction_times))
result_reaction_times = Listbox(results_frame)
for item in self.reaction_times:
result_reaction_times.insert('end', item)
desc_mean_reaction_time.grid(row=0, column=0)
desc_reaction_times.grid(row=1, column=0)
result_mean_reaction_time.grid(row=0, column=1)
result_reaction_times.grid(row=1, column=1)
desc_too_often = Label(results_frame, text="Bei richtiger Farbe zu oft gedrückt:")
desc_color_missed = Label(results_frame, text="Bei richtiger Farbe nicht gedrückt:")
desc_false_positives = Label(results_frame, text="Bei falscher Farbe gedrückt:")
result_too_often = Label(results_frame, text=self.key_too_often_pressed)
result_color_missed = Label(results_frame, text=self.color_missed)
result_false_positives = Label(results_frame, text=self.false_positives)
desc_too_often.grid(row=2, column=0)
desc_color_missed.grid(row=3, column=0)
desc_false_positives.grid(row=4, column=0)
result_too_often.grid(row=2, column=1)
result_color_missed.grid(row=3, column=1)
result_false_positives.grid(row=4, column=1)
results_frame.grid(row=0, column=0)
ok_button = Button(results_window, text="OK", padx=10, pady=10, command=results_window.quit)
ok_button.grid(row=1, column=0)
def main():
main_window = Tk()
game = Game(main_window)
main_window.bind_all("<Escape>", lambda e: game.show_results())
main_window.bind_all("<space>", lambda e: game.key_pressed()) # Ereignis Tastendruck
main_window.title("Spiel")
main_window.geometry('640x480')
start_button = Button(main_window, text="Start", padx=10, pady=10, command=game.start_game)
start_button.pack()
close_button = Button(main_window, text="Schließen", padx=10, pady=10, command=main_window.quit)
close_button.pack()
main_window.mainloop()
if __name__ == '__main__':
main()
Gruß
Atalanttore