Turtle 在嵌入式 Tkinter 窗口中无所事事

Turtle doing nothing in embedded Tkinter window

提问人:Akemi 提问时间:8/26/2023 最后编辑:ggorlenAkemi 更新时间:8/26/2023 访问量:33

问:

我正在尝试制作一个程序,您可以在其中绘制不同的形状。我已经设法将 turtlescreen 嵌入到我已经存在的 Tkinter one(根)中,并获得了一个 Tkinter Menu,我可以在其中运行不同的命令来绘制我的形状。

这是我的问题:如果您单击“形状”菜单中的任何形状,则不会发生任何事情。只会坐在屏幕上的某个地方,什么都不做。我没有收到任何错误代码或类似的东西,它应该可以正常工作。但是,事实并非如此。

可能,我只是瞎了又累(我正在不停地处理此代码近 5 小时),但我想修复此错误。所以,如果它在众目睽睽之下,我很抱歉。

这是我的代码:

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()

我试着画一个形状,它应该把送到中心,它应该开始画,但它只是坐在屏幕上的某个地方,一动不动。除了多次查看代码外,我并没有真正尝试任何事情。我真的不知道,我应该改变什么。

蟒蛇 tkinter python-turtle python-class

评论


答:

2赞 Tim Roberts 8/26/2023 #1

问题在于您组合使用 、 和 。tracer(0)resetupdate

tracer(0)意味着你不能看画画。所有更改都排队等待,直到调用。 擦除屏幕。因此,当被调用时,您的所有绘图都已被删除。updateresetupdate

删除电话,你会有幸福。reset

评论

0赞 ggorlen 8/26/2023
这是一个很好的例子,其中“分而治之”的最小化策略可能有助于 OP - 逐行删除每一行以尝试隔离问题,或者“逐行构建它”策略,两者都在最小可重现示例中描述以及如何调试小程序。鉴于 OP 大概只写了大约六行代码,而且其中大部分是提供样板的,这应该非常有效。
0赞 Ben A. 8/26/2023 #2

我现在在 Mac 上,所以我不得不将代码更改为通用代码——尽管 Python 的通用性很美,但并不太友好。因此,我所做的第一个更改是如何计算屏幕尺寸(使用 ),尽管这并不能解决问题。ctypesTKinter

正如 Tim 所说,您正在重置自己的绘图。如果你摆脱了它,你实际上可以看到画了什么。以下是我最终为我工作的东西:

from tkinter import *
from tkinter import Menu
from tkinter import Tk
import turtle as t
import math


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)


    def setup_turtle_screen(self):
        screen_width = self.root.winfo_screenwidth() # Note that this method is universal across platforms
        screen_height = self.root.winfo_screenheight()

        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 setup_turtle_screen(self):
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()

        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):
        start_x = self.root.winfo_screenwidth() / 2
        start_y = self.root.winfo_screenheight() / 2
        
        self.turtle.penup()
        self.turtle.goto(start_x, start_y)
        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() We can see our shape now!
        self.turtle_screen.update()

    def draw_square(self):
        start_x = self.root.winfo_screenwidth() / 2
        start_y = self.root.winfo_screenheight() / 2
        
        self.turtle.penup()
        self.turtle.goto(start_x, start_y)
        self.turtle.pendown()

        for _ in range(4):
            self.turtle.forward(100)
            self.turtle.right(90)

        # self.turtle.reset()  We comment this out so we can see our shape!
        self.turtle_screen.update()

Main()
`