我当前正在编写一个模块(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使我感到困惑,以至于我无法编写一个递归对象检查器,但是我仍然无法确定需要更改什么。
答案 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