如何修复Tkinter中的_tkinter.TclError: bad screen distance错误
问题解决:Tkinter报错"bad screen distance"
报错原因
你在button_hover函数里调用rage_button2.place_configure(x=obut_loc_x,y=obut_loc_y)时,传入的obut_loc_x和obut_loc_y是列表类型(比如[200,600,1000]),但Tkinter的place_configure方法要求x、y参数必须是单个数值,不能是列表,因此触发了_tkinter.TclError。
同时代码还有两个额外问题:
button_hover_easy和button_hover_hard函数里生成了随机坐标,但没有实际更新对应按钮的位置;gui.after(100)这种写法无效,after需要传入延迟时间和回调函数才能执行操作。
修复步骤及完整代码
1. 修正hover函数逻辑
每个难度对应的hover函数只负责更新自身按钮的位置,并且正确使用after实现延迟:
- 把位置更新逻辑封装成回调函数传给
after - 使用
random.choice获取单个坐标值,再传入place_configure
2. 优化难度切换逻辑
确保切换难度时只显示对应按钮,避免按钮叠加。
3. 修复标题窗口创建逻辑
原来的titlescreen重新创建了Tk实例,改为用Toplevel创建子窗口,避免生成多个主窗口。
以下是修复后的完整代码:
# You try to click a circle, but when you hover over it, it disappears from tkinter import * import random gui = Tk() def titlescreen(): # 使用Toplevel创建子窗口,避免生成多个主窗口 top = Toplevel(gui) top.configure(bg="limegreen") top.title("Rage Game Title screen") top.geometry("480x240") # 点击PLAY关闭标题窗口 play = Button(top, text=' PLAY ', font='helvetica,24', command=top.destroy) play.pack() top.after(1000000, top.destroy) gui.after(1, lambda: gui.focus_force()) gui.resizable(False, False) gui.configure(bg="limegreen") gui.title("Rage Game") gui.geometry("1280x800") my_label=Label(gui, text="",font='helvetica,12') my_label.pack(pady=50) # 坐标列表,共用即可,无需重复定义 loc_x = [200, 600, 1000] loc_y = [200, 350, 600] def press(): my_label.config(text="You pressed me.\n Well done\n") gui.after(1500, gui.destroy) def button_hover_hard(_): # 延迟100毫秒后更新困难模式按钮位置 def update_pos(): pos_x = random.choice(loc_x) pos_y = random.choice(loc_y) rage_button2.place_configure(x=pos_x, y=pos_y) gui.after(100, update_pos) def button_hover_easy(_): # 延迟200毫秒后更新简单模式按钮位置 def update_pos(): pos_x = random.choice(loc_x) pos_y = random.choice(loc_y) rage_button3.place_configure(x=pos_x, y=pos_y) gui.after(200, update_pos) def button_hover(_): # 延迟150毫秒后更新普通模式按钮位置 def update_pos(): pos_x = random.choice(loc_x) pos_y = random.choice(loc_y) rage_button.place_configure(x=pos_x, y=pos_y) gui.after(150, update_pos) def easy1234(): # 隐藏其他按钮,显示简单模式按钮 rage_button2.place_forget() rage_button.place_forget() rage_button3.place(x=600, y=350, anchor=CENTER) def normal1234(): # 隐藏其他按钮,显示普通模式按钮 rage_button3.place_forget() rage_button2.place_forget() rage_button.place(x=600, y=350, anchor=CENTER) def hard1234(): # 隐藏其他按钮,显示困难模式按钮 rage_button3.place_forget() rage_button.place_forget() rage_button2.place(x=600, y=350, anchor=CENTER) # 难度选择按钮 easy_btn = Button(gui, text=' EASY ', font='helvetica,24', command=easy1234) easy_btn.place(x=10, y=10) normal_btn = Button(gui, text=' NORMAL ', font='helvetica,24', command=normal1234) normal_btn.place(x=10, y=50) hard_btn = Button(gui, text=' HARD ', font='helvetica,24', command=hard1234) hard_btn.place(x=10, y=90) # 初始化三个难度的按钮,默认隐藏,切换难度时显示 rage_button3 = Button(gui, text=" Try to \n click me \n >:) ", borderwidth=0, command=press, height=3, width=5 ) rage_button3.place_forget() rage_button3.bind("<Enter>", button_hover_easy) rage_button2 = Button(gui, text=" Try to \n click me \n >:) ", borderwidth=0, command=press, height=3, width=5 ) rage_button2.place_forget() rage_button2.bind("<Enter>", button_hover_hard) rage_button = Button(gui, text=" Try to \n click me \n >:) ", borderwidth=0, command=press, height=3, width=5 ) # 默认显示普通模式按钮 rage_button.place(x=600, y=350, anchor=CENTER) rage_button.bind("<Enter>", button_hover) # 显示标题窗口 titlescreen() gui.mainloop()
内容的提问来源于stack exchange,提问作者THEOP05
相关产品推荐
相关产品推荐

