在Tkinter打字测速应用运行时,如何实时获取文本框输入值?
解决CTkTextbox实时输入比对问题
问题根源
- 代码仅在初始化和
start_test时各获取一次输入,没有持续监听输入变化,无法实现实时比对 tset_user_text仅被调用一次,缺乏循环执行逻辑,无法实时检查用户输入- 获取输入时未处理CTkTextbox自带的换行符,可能导致比对偏差
修改方案
- 移除
__init__中对tset_user_text的调用,改为在测试启动后通过window.after循环触发输入检查 - 新增循环检查函数,每次获取当前输入并处理换行符
- 调整
tset_user_text的统计逻辑,实时更新正确/错误字符数,避免累积错误
修改后的完整代码
def run_test(): random_number = random.randint(1, 5) test = session.query(data).filter(database.Database.id == random_number).first() return test class UserInterFace: def __init__(self): customtkinter.set_appearance_mode("dark") customtkinter.set_default_color_theme("green") self.window = CTk() self.window.title("Typing Speed Test Application") self.window.resizable(False, False) self.window.config(padx=50, pady=50) self.window.geometry("1000x700") self.test = run_test() self.wrong_entry = 0 self.correct_entry = 0 self.test_running = True self.start_count = 5 self.start_test_btn = None self.timer = None self.start_test_time = None self.end_test_time = None self.get_ready_label = CTkLabel(master=self.window, font=timer_font, text="Get ready Test will be start in :", text_color="#609EA2") self.count_down_label = CTkLabel(master=self.window, font=count_down_font, text=str(self.start_count), text_color="#820000") self.label_test = CTkLabel(master=self.window, font=my_font2, text="", wraplength=900, ) self.best_score_record = CTkLabel(master=self.window, font=my_font1, text_color="#609EA2", text="") self.type_area = CTkTextbox(master=self.window, width=900, height=200) self.main() self.window.mainloop() def start_test(self, test): self.start_test_time = time.time() self.get_ready_label.grid_forget() self.count_down_label.grid_forget() test_id = test.id test_text = test.text test_record = test.record self.label_test.configure(text=test_text) if test_record == 0: test_record = "No Record Yet" else: test_record = f"Best Record : {test_record}" self.best_score_record.configure(text=test_record) self.best_score_record.grid(row=0, column=0) self.label_test.grid(row=1, column=0, pady=(20, 0)) self.type_area.grid(row=2, column=0, pady=(20, 0)) self.type_area.focus_set() # 启动实时输入检查循环 self.check_input_loop() def main(self): self.start_test_btn = CTkButton(master=self.window, text="Start Test", command=lambda: self.start_time(), height=100, width=300, font=my_font1) self.start_test_btn.grid(row=0, column=0, padx=(300, 0), pady=(250, 0)) def start_time(self): if self.start_count >= 0: self.start_test_btn.grid_forget() self.get_ready_label.grid(row=0, column=0, pady=(50, 100), padx=(200, 0)) self.count_down_label.grid(row=1, column=0, padx=(200, 0)) self.count_down_label.configure(text=self.start_count) self.start_count -= 1 self.timer = self.window.after(1000, self.start_time) else: self.window.after_cancel(self.timer) self.start_test(self.test) def check_input_loop(self): if self.test_running: # 获取当前输入并去除末尾换行符 current_input = self.type_area.get("1.0", "end-1c") self.tset_user_text(self.test.text, current_input) # 每隔100ms再次检查,可根据需求调整间隔 self.window.after(100, self.check_input_loop) def tset_user_text(self, test_text, user_text): test_chars = list(test_text) user_chars = list(user_text) # 重置统计,避免每次检查累积计数 self.correct_entry = 0 self.wrong_entry = 0 # 只比对到两者中较短的长度,防止索引越界 compare_len = min(len(test_chars), len(user_chars)) for n in range(compare_len): if test_chars[n] == user_chars[n]: self.correct_entry += 1 else: self.wrong_entry += 1 # 检查是否完成输入 if len(user_chars) >= len(test_chars): self.test_running = False self.end_test_time = time.time() # 可在此添加测试结束后的结果展示逻辑 print(f"测试完成!正确字符:{self.correct_entry},错误字符:{self.wrong_entry}")
关键修改说明
check_input_loop函数:通过window.after循环调用,每隔100ms获取一次当前输入,实现实时监听- 使用
"end-1c"替代END获取输入,避免把CTkTextbox自动添加的换行符计入输入内容 tset_user_text每次检查前重置统计,确保计数是当前输入的实时结果,而非累积值
内容的提问来源于stack exchange,提问作者Pourya
相关产品推荐
相关产品推荐

