如何防止python的turtle模块打开默认窗口?

时间:2019-10-17 00:26:15

标签: python tkinter tkinter-canvas

我当前正在编写一个模块(myModule),该模块可以创建tkinter画布并将乌龟附加到其上。 模块的那部分完成了。但是,由于某种原因,当乌龟附着在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是turtle模块,而trI是RawTurtle的实例。

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

Turtle使我感到困惑,以至于我无法编写一个递归对象检查器,但是我仍然无法确定需要更改什么。

1 个答案:

答案 0 :(得分:0)

好的,我发现我出了问题。

解决方法是使用:

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

不仅仅是d[elem] = obj

结果是,当调用turtle的mainloop()时会创建默认窗口。

理论上,userProgram中的mainloop()是myModule中的mainloop()。不幸的是,由于attachTurtle()(更具体地说是d[elem] = obj),这个定义被乌龟的mainloop()覆盖了。因此,解决方法只是防止AttachTurtle()更改mainloop()。

要学习的教训是,如果要覆盖重要的定义,请检查正在创建的定义。

当解决方案如此简单时,我简直不敢涉足source code