嵌入Tkinter窗口的Turtle无响应,点击菜单无法绘图
问题描述
开发一款可绘制多种图形的程序,已成功将TurtleScreen嵌入Tkinter主窗口,并创建了Tkinter菜单触发不同图形绘制命令。但点击“Shapes”菜单中的任意图形选项,Turtle无任何动作,既不移动也不绘制图形,且无报错信息。
附上代码:
from tkinter import * import turtle as t import math from tkinter import Menu import ctypes title = "Turtle printer" button_width = 30 hypotenuse = 100 cathete = hypotenuse / math.sqrt(2) class Main: def __init__(self): self.setup_root() def setup_root(self): self.root = Tk() self.root.attributes("-fullscreen", True) self.root.title(title) self.canvas = Canvas(self.root) self.canvas.pack() self.turtle_screen = t.TurtleScreen(self.canvas) self.turtle_screen._RUNNING = True # Reactivate self.turtle = t.RawTurtle(self.turtle_screen) self.setup_turtle_screen() self.setup_file_menu() self.setup_shape_menu() self.root.mainloop() def exit_root(self): self.root.destroy() self.root.quit() def setup_file_menu(self): menu = Menu(self.root) self.root.config(menu=menu) filemenu = Menu(menu) filemenu.add_command(label="Exit", command=self.exit_root) def setup_shape_menu(self): menu = Menu(self.root) self.root.config(menu=menu) shapemenu = Menu(menu) menu.add_cascade(label="Shapes", menu=shapemenu) shapemenu.add_command(label="F", command=self.draw_f_shape) shapemenu.add_command(label="Square", command=self.draw_square) # Add more shape commands here def setup_turtle_screen(self): user32 = ctypes.windll.user32 screen_width = user32.GetSystemMetrics(0) screen_height = user32.GetSystemMetrics(1) self.canvas.config(width=screen_width, height=screen_height) self.turtle_screen.screensize(screen_width, screen_height) self.turtle_screen.setworldcoordinates(0, 0, screen_width, screen_height) self.turtle_screen.tracer(0) # Add shape drawing commands below def draw_f_shape(self): self.turtle.penup() self.turtle.goto(0, 0) self.turtle.pendown() self.turtle.left(90) self.turtle.forward(90) self.turtle.right(90) self.turtle.color("red") self.turtle.forward(60) self.turtle.back(60) self.turtle.left(90) self.turtle.color("black") self.turtle.forward(60) self.turtle.left(90) self.turtle.color("red") self.turtle.back(100) self.turtle.reset() self.turtle_screen.update() def draw_square(self): self.turtle.penup() self.turtle.goto(0, 0) self.turtle.pendown() for _ in range(4): self.turtle.forward(100) self.turtle.right(90) self.turtle.reset() self.turtle_screen.update() Main()
解决方案
问题出在三个核心点,逐一修复即可:
菜单覆盖问题
setup_file_menu和setup_shape_menu各自创建新的主菜单并覆盖root的菜单配置,导致菜单逻辑混乱。需要创建一个全局主菜单,两个子菜单都挂载到这个主菜单下。Turtle重置时机错误
绘制完成后调用self.turtle.reset()会直接清除画布所有图形并重置Turtle状态,导致刚画好的图形立刻消失。如果需要每次绘制前清空画布,应在绘制开始前调用self.turtle.clear(),而非绘制后调用reset()。退出逻辑顺序错误
exit_root中先调用destroy()再调用quit()会触发报错,应先终止主循环再销毁窗口。
修改后的完整代码:
from tkinter import * import turtle as t import math from tkinter import Menu import ctypes title = "Turtle printer" button_width = 30 hypotenuse = 100 cathete = hypotenuse / math.sqrt(2) class Main: def __init__(self): self.setup_root() def setup_root(self): self.root = Tk() self.root.attributes("-fullscreen", True) self.root.title(title) self.canvas = Canvas(self.root) self.canvas.pack(fill=BOTH, expand=True) # 让画布自适应窗口 self.turtle_screen = t.TurtleScreen(self.canvas) self.turtle_screen._RUNNING = True self.turtle = t.RawTurtle(self.turtle_screen) # 创建全局主菜单 self.main_menu = Menu(self.root) self.root.config(menu=self.main_menu) self.setup_turtle_screen() self.setup_file_menu() self.setup_shape_menu() self.root.mainloop() def exit_root(self): self.root.quit() # 先终止主循环 self.root.destroy() # 再销毁窗口 def setup_file_menu(self): filemenu = Menu(self.main_menu, tearoff=0) filemenu.add_command(label="Exit", command=self.exit_root) self.main_menu.add_cascade(label="File", menu=filemenu) def setup_shape_menu(self): shapemenu = Menu(self.main_menu, tearoff=0) shapemenu.add_command(label="F", command=self.draw_f_shape) shapemenu.add_command(label="Square", command=self.draw_square) self.main_menu.add_cascade(label="Shapes", menu=shapemenu) def setup_turtle_screen(self): user32 = ctypes.windll.user32 screen_width = user32.GetSystemMetrics(0) screen_height = user32.GetSystemMetrics(1) self.canvas.config(width=screen_width, height=screen_height) self.turtle_screen.screensize(screen_width, screen_height) self.turtle_screen.setworldcoordinates(0, 0, screen_width, screen_height) self.turtle_screen.tracer(0) # 关闭自动刷新,手动控制 def draw_f_shape(self): self.turtle.clear() # 绘制前清空画布 self.turtle.penup() self.turtle.goto(0, 0) self.turtle.pendown() self.turtle.setheading(0) # 重置朝向,避免之前的方向影响 self.turtle.left(90) self.turtle.forward(90) self.turtle.right(90) self.turtle.color("red") self.turtle.forward(60) self.turtle.back(60) self.turtle.left(90) self.turtle.color("black") self.turtle.forward(60) self.turtle.left(90) self.turtle.color("red") self.turtle.back(100) self.turtle_screen.update() # 手动刷新显示 def draw_square(self): self.turtle.clear() # 绘制前清空画布 self.turtle.penup() self.turtle.goto(0, 0) self.turtle.pendown() self.turtle.setheading(0) # 重置朝向 for _ in range(4): self.turtle.forward(100) self.turtle.right(90) self.turtle_screen.update() # 手动刷新显示 Main()
额外优化:
- 给画布添加
fill=BOTH, expand=True,确保画布填满整个窗口 - 绘制前添加
setheading(0)重置Turtle朝向,避免多次绘制后方向混乱
内容的提问来源于stack exchange,提问作者Akemi
相关产品推荐
相关产品推荐

