Как я могу привязать функцию к клавише возврата, когда генерируются мои кадры Tk? - PullRequest
0 голосов
/ 30 апреля 2020

Я пытаюсь привязать функцию validateSubmit к клавише ввода, чтобы тест можно было проходить на более высоких скоростях, однако я не могу понять, где или с чем пытаться его связать. Внутри основного внизу я прокомментировал привязку, с которой я чувствую, что получаю самые близкие результаты, однако я был в этом достаточно долго, чтобы знать, что это в настоящее время выходит за рамки моих знаний. Эта программа - мой набег в OOP. Я также получаю странную ошибку от validateSubmit, однако, похоже, она вызвана внутренним приведением типов tkinter и, похоже, не делает ничего, кроме как возвращает ошибку обратно в терминал.

##########################################################################################
#Imports
import tkinter as tk
from tkinter import ttk
from tkinter import Tk
from random import randint

########################################################################################## 
class Storage():
    def __init__(self):
        self.timeChoice = 0
        self.gameScore = 0
        self.answer = 0
        self.highScore = 0

    def set_timeChoice(self,x):
        self.timeChoice = x

    def set_gameScore(self,x):
        self.gameScore = x

    def set_answer(self,x):
        self.answer = x

    def set_highScore(self,x):
        self.highScore = x

    def save_highScore(self):
        timeChoiceVar = str(self.timeChoice)

        with open('data' + timeChoiceVar + '.txt',mode='w') as file:
            file.write(str(self.highScore))

    def get_highScore(self):
        timeChoiceVar = str(self.timeChoice)

        try:
            with open('data' + timeChoiceVar + '.txt',mode='r') as file:
                self.highScore = file.read()
        except:
            with open('data' + timeChoiceVar + '.txt',mode='w') as file:
                file.write('0')

##########################################################################################   
class AdditionApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self._frame = None
        self.switch_frame(SetTimePage)

    def switch_frame(self, frame_class):
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.grid(column=0,row=0,sticky=tk.W)

##########################################################################################
class SetTimePage(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)

        self.timeVar = tk.IntVar()
        data.set_timeChoice(60)

        time_frame = ttk.LabelFrame(self,text=' Test Timer Selection ')
        time_frame.grid(column=0,row=0,padx=6,pady=8,sticky='WE')

        radio1 = tk.Radiobutton(time_frame,text='1 Minute',variable=self.timeVar,value=60,command=lambda: data.set_timeChoice(self.timeVar.get()))
        radio1.grid(column=0,row=0,sticky=tk.W)
        radio1.select()

        radio2 = tk.Radiobutton(time_frame,text='2 Minutes',variable=self.timeVar,value=120,command=lambda: data.set_timeChoice(self.timeVar.get()))
        radio2.grid(column=0,row=1,sticky=tk.W)

        radio5 = tk.Radiobutton(time_frame,text='5 Minutes',variable=self.timeVar,value=300,command=lambda: data.set_timeChoice(self.timeVar.get()))
        radio5.grid(column=0,row=2,sticky=tk.W)

        radio10 = tk.Radiobutton(time_frame,text='10 Minutes',variable=self.timeVar,value=600,command=lambda: data.set_timeChoice(self.timeVar.get()))
        radio10.grid(column=0,row=3,sticky=tk.W)

        start_button = ttk.Button(self,text=' Start ',command=lambda: master.switch_frame(TestPage))
        start_button.grid(column=0,row=1,sticky='WE',pady=4)

##########################################################################################
class TestPage(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)        
        self.answer = tk.IntVar()
        self.scoreVar = 0
        data.set_gameScore(0)
        data.get_highScore()

        self.test_frame = tk.Label(self,text=data.timeChoice)
        self.test_frame.grid(column=3,row=0,sticky=tk.N)

        self.score_frame = tk.Label(self,text='Score: %d' % data.gameScore)
        self.score_frame.grid(column=3,row=1,sticky=tk.N)

        self.high_score_frame = tk.Label(self,text='High Score: %s' % data.highScore)
        self.high_score_frame.grid(column=3,row=2,sticky=tk.N)

        self.solve_frame = ttk.LabelFrame(self,text=' Solve: ')
        self.solve_frame.grid(column=0,row=1,columnspan=2,padx=12,sticky=tk.W)

        self.equation_label = tk.Label(self.solve_frame,text='')
        self.equation_label.grid(column=0,row=0,padx=6,sticky=tk.W)

        self.answer_box = ttk.Entry(self.solve_frame,width=2,textvariable=self.answer)
        self.answer_box.grid(column=1,row=0,padx=12,sticky=tk.W)
        self.answer_box.bind('<Return>', self.validateSubmit)

        self.back_button = ttk.Button(self.solve_frame,text=' Back ',command=lambda: master.switch_frame(SetTimePage))
        self.back_button.grid(column=3,row=0,padx=12,sticky=tk.N)

        self.countdown(data.timeChoice)


    def countdown(self, remaining = None):
        if remaining is not None:
            self.remaining = remaining
            self.generateEquation()
        if self.remaining < 0:
            self.test_frame.configure(text=" Time's up! ")
            self.submit_answer.configure(state='disabled')
            self.answer_box.configure(state='disabled')
        else:
            self.test_frame.configure(text="Seconds remaining: %d" % self.remaining)
            self.high_score_frame.configure(text='High Score: %s' % data.highScore)
            self.submit_answer.bind('<Return>', self.validateSubmit)
            self.remaining = self.remaining - 1
            self.after(1000, self.countdown)

    def generateEquation(self): 
        self.x = randint(0,10)
        self.y = randint(0,10)
        self.z = 0
        self.equation_label.configure(text='%d + %d' % (self.x , self.y))
        self.answer_box.delete(0,3)
        self.answer_box.focus()
        self.submit_answer = ttk.Button(self.solve_frame,text=' Submit ',command=self.validateSubmit)
        self.submit_answer.grid(column=2,row=0,padx=12,sticky=tk.E)


    def validateSubmit(self,event=None):
        while self.remaining >= 0:
            self.z = self.answer.get()
            if self.x + self.y == self.z:
                self.scoreVar += 1
                data.set_gameScore(self.scoreVar)
                self.score_frame.configure(text='Score: %d' % data.gameScore)
                self.generateEquation()
                if int(data.highScore) < data.gameScore:
                    data.set_highScore(data.gameScore)
                    data.save_highScore()
            elif self.x + self.y != self.z :
                self.generateEquation()


##########################################################################################
if __name__ == "__main__":
    data = Storage()
    program = AdditionApp()
    program.title(' Addition Test ')
    #program.bind('<Return>', TestPage.validateSubmit)
    program.mainloop()
    data.save_highScore

1 Ответ

1 голос
/ 30 апреля 2020

Если вы хотите, чтобы пользователь мог нажимать клавишу возврата после ввода ответа вместо нажатия кнопки Submit, тогда привязка должна быть go на виджете ввода, поскольку это виджет с фокусом клавиатуры.

self.answer_box.bind('<Return>', self.validateSubmit)

Кроме того, вам необходимо убедиться, что validateSubmit может принять переданный параметр event. Поскольку вы хотите использовать его как для привязки, так и для нажатия кнопки, самый простой способ сделать это то есть аргумент event необязательный:

def validateSubmit(self, event=None):
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...