【问题标题】:How do I prevent python's turtle module from opening the default window?如何防止python的turtle模块打开默认窗口?
【发布时间】:2019-10-17 00:26:15
【问题描述】:

我目前正在编写一个模块(myModule),它可以创建一个 tkinter 画布并将一个海龟附加到它上面。 模块的那部分已经完成。但是,由于某种原因,turtle 在附加到 tkinter 画布时仍会打开另一个窗口。我想避免这种情况,但我不知道怎么做,而且海龟文档很糟糕。

这是我到目前为止所做的相关部分:

#myModule
import tkinter as tk
import turtle as tr
import inspect as ins
from functools import partial

_root = None
_canvas = None
_turtle = None
d = None

def openWindow():
    global _root
    global d

    if d == None:
        myFrame = sys._getframe()
        aboveFrameName = myFrame.f_back.f_back.f_back.f_globals["__name__"] #This doesnt make sense, but it works.
        userModule = sys.modules[aboveFrameName]
        d = userModule.__dict__

    _root = tk.Tk()


def attachCanvas():
    global _canvas
    if _root == None:
        openWindow()

    _canvas = tk.Canvas(_root, bd = 0, highlightthickness = 0, width = 500, height = 500)
    _canvas.pack()


def attachTurtle():
    global _turtle
    global _canvas
    global _screen
    global d
    if _canvas == None:
        attachCanvas()

    _turtle = tr.RawTurtle(_canvas)

    for key in tr.__dict__.keys():
        obj = None
        if key in tr.TNavigator.__dict__.keys():  #Checks if the object also exists in TNavigator
            obj = getattr(tr.TNavigator, key)
            if hasattr(obj, "__call__") and ("self" in ins.getargspec(obj)[0]): #Checks if the function 
                                                                                 uses a self argument
                obj = partial(obj, _turtle) #Pass in the turtle we just created automatically
        else:
            obj = getattr(tr, key)
        d[key] = obj   #Transfer object reference from myModule to userProgram

    return _turtle


def mainloop():
    tk.mainloop()


#userProgram
from myModule import *

attachTurtle()
forward(100)
mainloop()

注意:假设 trM 是海龟模块,而 trI 是 RawTurtle 的一个实例。

例如,我注意到trM.forward(10) 应用于默认屏幕,而 trI.forward(x) 应用于 tkinter 屏幕。此外,诸如 forward(x) 之类的函数(在完成 from turtle import * 之后)实际上正在调用 trM.TNavigator.forward(trI, x)。

Turtle 让我很困惑,以至于我编写了一个递归对象检查器,但我仍然不知道需要更改什么。

【问题讨论】:

标签: python tkinter tkinter-canvas


【解决方案1】:

好的,我找到了哪里出错了。

解决方法是使用:

if elem != "mainloop":
    d[elem] = obj

而不仅仅是d[elem] = obj

原来默认窗口是在turtle的mainloop()被调用时创建的。

理论上,userProgram 中的 mainloop() 就是 myModule 中的 mainloop()。不幸的是,由于 attachTurtle()(更具体地说是d[elem] = obj),这个定义被海龟的 mainloop() 覆盖。所以修复只是为了防止 attachTurtle() 改变 mainloop()。

要吸取的教训是检查您正在创建的定义,以防覆盖重要的定义。

我不敢相信我去挖掘 source code 时解决方案这么简单

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 2022-06-25
    • 1970-01-01
    • 2022-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多