0

So I've been working on a program called tdc (Turtle Design Creator), which basically uses Tkinter buttons to control a Turtle. The code:

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)

(I know it's a lot of code!) But whenever I run it and click the Right 90 or Left 90 buttons, I get this error:

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'

What exactly is happening? All the other buttons work fine, and they have the same setup as left() (or right()).

Please help...

1 Answer 1

2

It's likely because you have two functions called 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')

and two functions called 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')

Rename one pair and see if things improve

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)

I know it's a lot of code!

I've reworked it below to make it slightly less code -- see if the changes make sense for your purposes. You're walking a tightrope when mixing Tk with turtle (which is built atop Tk) -- you've done an excellent job so far, just be aware the two can clash if/when you run into bugs.

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()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.