【问题标题】:(Python 3) Odd error with Turtle controller ultilising Tkinter(Python 3) Turtle 控制器使用 Tkinter 时出现奇怪错误
【发布时间】:2016-12-17 17:04:53
【问题描述】:

所以我一直在开发一个名为 tdc(Turtle Design Creator)的程序,它基本上使用 Tkinter 按钮来控制 Turtle。代码:

global file
file = None
global rcd
rcd = False
global arrows
arrows = False
global arrowtoggle
def forwardless():
    t.forward(25)
    if rcd:
        file.write('t.forward(25)\n')
def backwardless():
    t.backward(25)
    if rcd:
        file.write('t.backward(25)\n')
def forward():
    t.forward(50)
    if rcd:
        file.write('t.forward(50)\n')
def left():
    t.left(90)
    if rcd:
        file.write('t.left(90)\n')
def right():
    t.right(90)
    if rcd:
        file.write('t.right(90)\n')
def diagleft():
    t.left(45)
    if rcd:
        file.write('t.left(45)\n')
def diagright():
    t.right(45)
    if rcd:
        file.write('t.right(45)\n')
def clear():
    t.reset()
    if rcd:
        file.write('t.reset()\n')
def backward():
    t.backward(50)
    if rcd:
        file.write('t.backward(50)\n')
def lift():
    t.up()
    if rcd:
        file.write('t.up()\n')
def drop():
    t.down()
    if rcd:
        file.write('t.down()\n')
def green():
    t.color(0, 0.5, 0)
    if rcd:
        file.write('t.color(0, 0.5, 0)\n')
def red():
    t.color(1, 0, 0)
    if rcd:
        file.write('t.color(1, 0, 0)\n')
def gold():
    t.color(0.9, 0.75, 0)
    if rcd:
        file.write('t.color(0.9, 0.75, 0)\n')
def blue():
    t.color(0, 0, 1)
    if rcd:
        file.write('t.color(0, 0, 1)\n')
def black():
    t.color(0, 0, 0)
    if rcd:
        file.write('t.up()\n')
def begin_fill():
    t.begin_fill()
    if rcd:
        file.write('t.begin_fill()\n')
def end_fill():
    t.end_fill()
    if rcd:
        file.write('t.end_fill()\n')
def small_circle():
    t.circle(10)
    if rcd:
        file.write('t.circle(10)\n')
def medium_circle():
    t.circle(30)
    if rcd:
        file.write('t.circle(30)\n')
def large_circle():
    t.circle(50)
    if rcd:
        file.write('t.circle(50)\n')
def steepdiagleft():
    t.left(25)
    if rcd:
        file.write('t.left(25)\n')
def steepdiagright():
    t.right(25)
    if rcd:
        file.write('t.right(25)\n')
def arrowkey():
    global arrows
    global arrowtoggle
    if not arrows:
        arrows = True
        arrowtoggle.config(text="Arrow Key Control: ON")
    else:
        arrows = False
        arrowtoggle.config(text="Arrow Key Control: OFF")
def right(event):
    global arrows
    global rcd
    if arrows:
        t.setheading(0)
        t.forward(5)
        if rcd:
            file.write('t.setheading(0)\nt.forward(5)\n')
def left(event):
    global arrows
    global rcd
    if arrows:
        t.setheading(180)
        t.forward(5)
        if rcd:
            file.write('t.setheading(180)\nt.forward(5)\n')
def up(event):
    global arrows
    global rcd
    if arrows:
        t.setheading(90)
        t.forward(5)
        if rcd:
            file.write('t.setheading(90)\nt.forward(5)\n')
def down(event):
    global arrows
    global rcd
    if arrows:
        t.setheading(270)
        t.forward(5)
        if rcd:
            file.write('t.setheading(270)\nt.forward(5)\n')
def startrcd():
    global rcd
    rcd = True
    global file
    while file == None:
        file = filedialog.asksaveasfile(mode="w", defaultextension=".py")
        if file == None:
            messagebox.showinfo('Recording Canceled', 'No file selected or created.')
            break
    if file != None:
        file.write('import turtle\nturtle.title(\'TDC Save\')\nturtle.setup(width=1000, height=500)\nt = turtle.Pen()\n')
        messagebox.showinfo('Started', 'Recording started.')
def endrcd():
    global rcd
    global file
    if rcd and file != None:
        rcd = False
        file.close()
        file = None
        messagebox.showinfo('Ended', 'Recording ended.')
def close():
    if messagebox.askyesno('Exit?', 'Are you sure you wish to exit?'):
        messagebox.showinfo('Closing', 'TDC is closing.')
        exit()
import turtle
import tkinter.messagebox
from tkinter import filedialog
turtle.setup(width=1000, height=500)
turtle.title('Turtle Design Creator')
t = turtle.Pen()
from tkinter import *
tk = Tk()
tk.title("Toolbox")
a = Button(tk, text="Forward 50", command=forward)
b = Button(tk, text="Left 90", command=left)
c = Button(tk, text="Right 90", command=right)
d = Button(tk, text="Left 45", command=diagleft)
e = Button(tk, text="Right 45", command=diagright)
f = Button(tk, text="Clear", command=clear)
g = Button(tk, text="Backward 50", command=backward)
h = Button(tk, text="Lift", command=lift)
i = Button(tk, text="Drop", command=drop)
j = Button(tk, text="Green", command=green)
k = Button(tk, text="Red", command=red)
l = Button(tk, text="Gold", command=gold)
m = Button(tk, text="Blue", command=blue)
n = Button(tk, text="Black", command=black)
o = Button(tk, text="Begin Fill", command=begin_fill)
p = Button(tk, text="End Fill", command=end_fill)
q = Button(tk, text="Small Circle", command=small_circle)
r = Button(tk, text="Medium Circle", command=medium_circle)
s = Button(tk, text="Large Circle", command=large_circle)
tt = Button(tk, text="Left 25", command=steepdiagleft)
u = Button(tk, text="Right 25", command=steepdiagright)
v = Button(tk, text="Start Recording", command=startrcd)
w = Button(tk, text="End Recording", command=endrcd)
x = Button(tk, text="Exit", command=close)
y = Button(tk, text="Forward 25", command=forwardless)
z = Button(tk, text="Backward 25", command=backwardless)
arrow = Button(tk, text="Arrow Key Control Toggle\n(only 90 degree angles)", command=arrowkey)
arrowtoggle = Label(tk, text="Arrow Key Control: OFF")
a.pack()
b.pack()
c.pack()
d.pack()
e.pack()
f.pack()
g.pack()
h.pack()
i.pack()
j.pack()
k.pack()
l.pack()
m.pack()
n.pack()
o.pack()
p.pack()
q.pack()
r.pack()
s.pack()
tt.pack()
u.pack()
v.pack()
w.pack()
x.pack()
y.pack()
z.pack()
arrow.pack()
arrowtoggle.pack()
tk.bind("<Right>", right)
tk.bind("<Left>", left)
tk.bind("<Up>", up)
tk.bind("<Down>", down)

(我知道代码很多!) 但是每当我运行它并单击右 90 或左 90 按钮时,我都会收到此错误:

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.4/idlelib/run.py", line 121, in main
seq, request = rpc.request_queue.get(block=True, timeout=0.05)
File "/usr/lib/python3.4/queue.py", line 175, in get
raise Empty
queue.Empty

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3.4/tkinter/__init__.py", line 1536, in __call__
return self.func(*args)
TypeError: left() missing 1 required positional argument: 'event'

到底发生了什么?所有其他按钮都可以正常工作,并且它们的设置与 left()(或 right())相同。

请帮忙...

【问题讨论】:

    标签: python python-3.x tkinter turtle-graphics


    【解决方案1】:

    这可能是因为您有两个名为 left() 的函数:

    def left():
        t.left(90)
        if rcd:
            file.write('t.left(90)\n')
    
    def left(event):
        global arrows
        global rcd
        if arrows:
            t.setheading(180)
            t.forward(5)
            if rcd:
                file.write('t.setheading(180)\nt.forward(5)\n')
    

    还有两个名为right()的函数:

    def right():
        t.right(90)
        if rcd:
            file.write('t.right(90)\n')
    
    def right(event):
        global arrows
        global rcd
        if arrows:
            t.setheading(0)
            t.forward(5)
            if rcd:
                file.write('t.setheading(0)\nt.forward(5)\n')
    

    重命名一对,看看情况是否有所改善

    def hard_left():
        t.left(90)
        if rcd:
            file.write('t.left(90)\n')
    def hard_right():
        t.right(90)
        if rcd:
            file.write('t.right(90)\n')
    
    # ...
    
    b = Button(tk, text="Left 90", command=hard_left)
    c = Button(tk, text="Right 90", command=hard_right)
    

    我知道代码很多!

    我在下面对其进行了重新设计,以减少代码量——看看这些更改是否对您的目的有意义。将 Tk 与 Turtle(构建在 Tk 之上)混合在一起时,您正在走钢丝——到目前为止,您已经做得很好,请注意,如果/当您遇到错误时,两者可能会发生冲突。

    import turtle
    from tkinter import *
    from tkinter import filedialog
    
    file = None
    rcd = False
    arrows = False
    
    def forward(distance=50):
        t.forward(distance)
        if rcd:
            file.write('t.forward({})\n'.format(distance))
    
    def backward(distance=50):
        t.backward(distance)
        if rcd:
            file.write('t.backward({})\n'.format(distance))
    
    def left(angle=90):
        t.left(angle)
        if rcd:
            file.write('t.left({})\n'.format(angle))
    
    def right(angle=90):
        t.right(angle)
        if rcd:
            file.write('t.right({})\n'.format(angle))
    
    def clear():
        t.reset()
        if rcd:
            file.write('t.reset()\n')
    
    def lift():
        t.up()
        if rcd:
            file.write('t.up()\n')
    
    def drop():
        t.down()
        if rcd:
            file.write('t.down()\n')
    
    def color(r=0, g=0, b=0):
        t.color(r, g, b)
        if rcd:
            file.write('t.color({}, {}, {})\n'.format(r, g, b))
    
    def begin_fill():
        t.begin_fill()
        if rcd:
            file.write('t.begin_fill()\n')
    
    def end_fill():
        t.end_fill()
        if rcd:
            file.write('t.end_fill()\n')
    
    def circle(radius=30):
        t.circle(radius)
        if rcd:
            file.write('t.circle({})\n'.format(radius))
    
    def arrowkey():
        global arrows
    
        if not arrows:
            arrows = True
            arrowtoggle.config(text="Arrow Key Control: ON")
        else:
            arrows = False
            arrowtoggle.config(text="Arrow Key Control: OFF")
    
    def handle_right(event):
        if arrows:
            t.setheading(0)
            t.forward(5)
            if rcd:
                file.write('t.setheading(0)\nt.forward(5)\n')
    
    def handle_left(event):
        if arrows:
            t.setheading(180)
            t.forward(5)
            if rcd:
                file.write('t.setheading(180)\nt.forward(5)\n')
    
    def handle_up(event):
        if arrows:
            t.setheading(90)
            t.forward(5)
            if rcd:
                file.write('t.setheading(90)\nt.forward(5)\n')
    
    def handle_down(event):
        if arrows:
            t.setheading(270)
            t.forward(5)
            if rcd:
                file.write('t.setheading(270)\nt.forward(5)\n')
    
    def startrcd():
        global rcd, file
    
        rcd = True
    
        while file is None:
            file = filedialog.asksaveasfile(mode="w", defaultextension=".py")
            if file is None:
                messagebox.showinfo('Recording Canceled', 'No file selected or created.')
                break
        if file != None:
            file.write("import turtle\nturtle.title('TDC Save')\n")
            file.write('turtle.setup(width=1000, height=500)\n')
            file.write('t = turtle.Turtle()\n')
            messagebox.showinfo('Started', 'Recording started.')
    
    def endrcd():
        global rcd, file
    
        if rcd and file is not None:
            rcd = False
            file.close()
            file = None
            messagebox.showinfo('Ended', 'Recording ended.')
    
    def close():
        if messagebox.askyesno('Exit?', 'Are you sure you wish to exit?'):
            messagebox.showinfo('Closing', 'TDC is closing.')
            exit()
    
    turtle.setup(width=1000, height=500)
    turtle.title('Turtle Design Creator')
    t = turtle.Turtle()
    
    tk = Tk()
    tk.title("Toolbox")
    
    items = []
    
    items.append(Button(tk, text="Forward 50", command=forward))
    items.append(Button(tk, text="Left 90", command=left))
    items.append(Button(tk, text="Right 90", command=right))
    items.append(Button(tk, text="Left 45", command=lambda: left(45)))
    items.append(Button(tk, text="Right 45", command=lambda: right(45)))
    items.append(Button(tk, text="Clear", command=clear))
    items.append(Button(tk, text="Backward 50", command=backward))
    items.append(Button(tk, text="Lift", command=lift))
    items.append(Button(tk, text="Drop", command=drop))
    items.append(Button(tk, text="Green", command=lambda: color(0, 0.5, 0)))
    items.append(Button(tk, text="Red", command=lambda: color(1, 0, 0)))
    items.append(Button(tk, text="Gold", command=lambda: color(0.9, 0.75, 0)))
    items.append(Button(tk, text="Blue", command=lambda: color(0, 0, 1)))
    items.append(Button(tk, text="Black", command=lambda: color(0, 0, 0)))
    items.append(Button(tk, text="Begin Fill", command=begin_fill))
    items.append(Button(tk, text="End Fill", command=end_fill))
    items.append(Button(tk, text="Small Circle", command=lambda: circle(10)))
    items.append(Button(tk, text="Medium Circle", command=circle))
    items.append(Button(tk, text="Large Circle", command=lambda: circle(50)))
    items.append(Button(tk, text="Left 25", command=lambda: left(25)))
    items.append(Button(tk, text="Right 25", command=lambda: right(25)))
    items.append(Button(tk, text="Start Recording", command=startrcd))
    items.append(Button(tk, text="End Recording", command=endrcd))
    items.append(Button(tk, text="Exit", command=close))
    items.append(Button(tk, text="Forward 25", command=lambda: forward(25)))
    items.append(Button(tk, text="Backward 25", command=lambda: backward(25)))
    items.append(Button(tk, text="Arrow Key Control Toggle\n(only 90 degree angles)", command=arrowkey))
    
    arrowtoggle = Label(tk, text="Arrow Key Control: OFF")
    items.append(arrowtoggle)
    
    for item in items:
        item.pack()
    
    tk.bind("<Right>", handle_right)
    tk.bind("<Left>", handle_left)
    tk.bind("<Up>", handle_up)
    tk.bind("<Down>", handle_down)
    
    turtle.mainloop()
    

    【讨论】:

      猜你喜欢
      • 2016-04-29
      • 2019-03-10
      • 2013-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-30
      • 2013-05-05
      • 2015-12-07
      相关资源
      最近更新 更多