python-3.x - 生成 Tk 帧时,如何将函数绑定到返回键?
问题描述
我正在尝试将函数 validateSubmit 绑定到 enter 键,以便可以以更快的速度进行测试,但是我无法确定尝试将其绑定到的位置或内容。在底部的主要内容中,我注释掉了我觉得我得到最接近结果的绑定,但是我已经有足够长的时间知道它目前超出了我的知识范围。这个程序是我对 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
解决方案
如果您希望用户能够在输入答案后按回车而不是按Submit
按钮,那么绑定需要在输入小部件上进行,因为这是具有键盘焦点的小部件。
self.answer_box.bind('<Return>', self.validateSubmit)
此外,您需要确保它validateSubmit
可以接受event
传入的选项。由于您希望将它用于绑定和按钮单击,最简单的方法是使event
参数可选:
def validateSubmit(self, event=None):
推荐阅读
- android - 如何避免 FragmentManager 重新创建片段?
- xcode - SwiftUI / Xcode 错误 - 更新时间超过 5 秒
- mysql - GROUP BY 语法 Mysql - 省略可分组的列
- react-native - 在 React Native 中使用 flex 进行网格布局
- javascript - 如何使用 MapBox 获取过滤多边形的坐标?
- javascript - Node.js:console.err() 是同步的还是异步的?
- spring-integration - 使用 Spring Integration 从远程 SFTP 目录和子目录流式传输
- python - Holoviews 绘制多维网格数据
- ajax - 通过地理服务器将空的、发布请求文本/xml 插入到 postgis 整数字段
- java - GWT - 是否手动删除分离/卸载所需的本机事件处理程序?