Plz Help with this runtime error:_tkinter.TclError: item "12" doesn't exist

I am getting the following runtime error for the code shown below:

_ test setting ondrag for seltt <turtle.Turtle object at 0xb5d54a10>)
seltt.onftsg= <bound method RawTurtle.ondrag of <turtle.Turtle object at 0xb5d54a10>>
Exception in Tkinter callback
Traceback (most recent call last):
File “/usr/lib/python3.7/tkinter/”, line 1705, in call
return self.func(*args)
File “/usr/lib/python3.7/”, line 675, in eventfun
fun(x, y)
File “”, line 200, in selectobs
File “/usr/lib/python3.7/”, line 3587, in ondrag
self.screen._ondrag(self.turtle._item, fun, btn, add)
File “/usr/lib/python3.7/”, line 658, in _ondrag, “<Button%s-Motion>” % num, eventfun, add)
File “”, line 1, in tag_bind
File “/usr/lib/python3.7/tkinter/”, line 2453, in tag_bind
sequence, func, add)
File “/usr/lib/python3.7/tkinter/”, line 1206, in _bind + (sequence, cmd))
_tkinter.TclError: item “12” doesn’t exist

segment of script where this error occurs

178 def selectobs(self, x,y):
179 for ob in self.obstacles:
180 xhi, xlo = ob.range[0]
181 yhi, ylo = ob.range[1]
182 print(“selectobs ----\n x {0} y {1} xhi {4} xlo {5} yhi {6} ylo {7} range {2} issel {3}”.format(x,y,ob.range, ob.isselected, xhi, xlo, yhi, ylo))
183 if x <= xhi and x >= xlo and y <= yhi and y >= ylo:
184 if self.selectedobs != None:
185 self.selectedobs.setselected(False, self.seltt)
186 print(f" test setting ondrag for seltt {self.seltt})\n seltt.onftsg= {self.seltt.ondrag}")
187 “”"
188 self.scrn.onclick(self.selectobs)
189 self.scrn.onclick(None)
194 self.seltt.onrelease(self.selectobs)
195 self.seltt.onrelease(None)
198 self.seltt.ondrag(None)
199 “”"
200 self.seltt.ondrag(
201 ob.setselected(True, self.seltt)
202 self.selectedobs = ob
203 print(“selectobs this is it ob ----\n”, ob)

This code has been working for weeks then this error started showing up,
I have commented out a block of debugginh statements trying to undeer stand what it doesn’t like,
Setting mouse events on the screen works fine.
Setting any mouse event on a turtle creates this error
ondrag shows item “12” doesn’t exist
onclick or onrelease shows item “9” doesn;t exist

What’s happening here?
What do I look at to fine what went wrong?

Thanks for any insight you can give on this issue.

1 Like

Could you please post complete code so we can debug?

1 Like

Thanks for your interest, Attached is the complete script.
to create the error dor the following:
When the program opens there is a turtle window with a menu at the top.
Menu item ar activated via the indicated key.
press “p” for playground, then “o” for obstacles then “d” for draw
when you left click on the screen a turtle will appear.
You can drag this turtle to form a side of a polygon, releasing the mouse completes the side
Once you complete at least two sides a right click will close and complete the polygon.
now key “d” again taking it out of the draw mode.
this makes the polygon delectable for further operations like translate or rotate.
Click on the polygon to select it. This is when the error occurs.

Thanks again,


(Attachment is missing)

1 Like

The forum says “(Attachment is missing)”. Maybe try to post inline? Use triple backticks like this:

Code goes here.
1 Like

Here is the script

import turtle
import math

def main():
print("myrobot sv1 lets go")

SnapDistance = 5
RotationGuideTicks = 24
wn = turtle.Screen()
shp = ((-10, 0), (10, 0), (0, 0), (0, 10), (0, -10), (0, 0))
wn.register_shape("cross", shp)

# some string colors
TBLACK = '\033[30m'
TRED = '\033[31m'
TGREEN = '\033[32m'
TYELLOW = '\033[33m'
TBLUE = '\033[34m'
TPURPLE = '\033[35m'
TCYAN = '\033[36m'
TWHITE = '\033[37m'
ENDC = '\033[m'

class workspaces:

def __init__(self, scrn):
self.workspaces = {}
self.scrn = scrn
self.activeworkspace = None
[]( = turtle.Turtle()
h = self.scrn.window_height()
w = self.scrn.window_width()
self.stop = (h-22)/2
self.xside = (w-22)/2
self.mbox = ((-self.xside, self.stop),(self.xside, self.stop),(self.xside, self.stop-20),(-self.xside, self.stop-20))
self.lastmenutxt = "Welcome"

def appendworkspace(self, ws):
self.workspaces[[](] = ws
print("appendworkspace ws ", ws, " workspaces ",self.workspaces)
#input("adding ws")

def setactiveworkspace(self, name):
ws = self.getworkspace(name)
print("setactiveworkspace name {0} ws {1} ws=None {2}\n wkspcs {3}".format(name, ws, ws==None, self.workspaces))
if ws == None:
self.activeworkspace = ws

def getworkspace(self, name=None):
"""Return named workspace, if name = None return activeworkspace"""
if name == None:
return self.activeworkspace
return self.workspaces.get(name, None)

def drawmbox(self):"black","darkblue")
x,y = self.mbox[0],y)
for i in range(1,4):
x,y = self.mbox[i],y)
x,y = self.mbox[3] #position for write,y-2)"white"), font=("Arial", 16, "normal"))

def write_menu(self, txt):, font=("Arial", 14, "normal"))
self.lastmenutxt = txt

def redrawmenu(self):

class workspace:

def __init__(self, name, item, wkspcs):
[]( = name
self.item = item
self.workspaces = wkspcs

def displayworkspace(self):

class playground:
"""this is the robots playground"""
def __init__(self, w, bgcolor="lightgrey"):
self.scrn = w
[]( = turtle.Turtle()
self.seltt = turtle.Turtle()
self.mkrtt = turtle.Turtle()
self.mkrtt2 = turtle.Turtle()
self.bgcolor = bgcolor
self.obstacles = []
self.robots = {}
self.selectedobs = None
self.lastloadfn = ""
self.lastsavefn = ""
h = self.scrn.window_height()
w = self.scrn.window_width()
self.stop = (h-22)/2
self.xside = (w-22)/2
self.mbox = ((-self.xside, self.stop),(self.xside, self.stop),(self.xside, self.stop-20),(-self.xside, self.stop-20))

def __str__(self):
rslt = "playg: scrn {0} tt {1} seltt {2} obs {3} rbots {4}"
rslt = rslt.format(self.scrn, [](, self.seltt, self.obstacles, self.robots)
return rslt

def displayme(self):
for o in self.obstacles:
def drawmbox(self):"black","darkblue")
x,y = self.mbox[0],y)
for i in range(1,4):
x,y = self.mbox[i],y)
x,y = self.mbox[3] #position for write,y-2)"white")"Welcome",font=("Arial", 16, "normal"))

def write_menu(self, txt):, font=("Arial", 16, "normal"))

def selectobs(self, x,y):
for ob in self.obstacles:
xhi, xlo = ob.range[0]
yhi, ylo = ob.range[1]
print("selectobs ----\n x {0} y {1} xhi {4} xlo {5} yhi {6} ylo {7} range {2} issel {3}".format(x,y,ob.range, ob.isselected, xhi, xlo, yhi, ylo))
if x <= xhi and x >= xlo and y <= yhi and y >= ylo:
if self.selectedobs != None:
self.selectedobs.setselected(False, self.seltt)
print(f" test setting ondrag for seltt {self.seltt})\n seltt.onftsg= {self.seltt.ondrag}")
ob.setselected(True, self.seltt)
self.selectedobs = ob
print("selectobs this is it ob ----\n", ob)

def saveplayg(self):
dflt = self.lastsavefn
if dflt == "":
dflt = self.lastloadfn
fn = getfilename(dflt, "save", ".obs")
if fn != None:
print("saving obs to ", fn)
fo = open(fn, "w")
for o in pg.obstacles:
s = "obstacle\n"
s = "border_color=" + o.border_color + "\n"
s = "fill_color=" + o.fill_color + "\n"
s = "border_size=" + str(o.border_size) + "\n"
s = "poly=" + str(o.poly) + "\n"
self.lastsavefn = fn
print("Leaving saveplayg")

def loadplayg(self):
dflt = self.lastloadfn
if dflt == "":
dflt = self.lastsavefn
fn = getfilename(dflt, "load", ".obs")
if fn != None:
fi = open(fn, "r")
while True:
s = fi.readline()
if len(s) == 0:
l = s.split("=")
if l[0] == "obstacle":
if l[0] == "fill_color":
fc = str(l[1])
if l[0] == "border_color":
bc = str(l[1])
if l[0] == "border_size":
bz = int(l[1])
if l[0] == "poly":
print("from obs l[1] {6} bc {0} tytpe(bc) {1} fc {2} type(fc) {3} bz {4} type(bz) {5}".format(bc,type(bc),fc,type(fc),bz,type(bz), l[1]))
p = strtopoly(l[1])
print("load poly ", p)
x,y = p[0]
o = obstacle(x, y, wn, pg, obstacle.begin_obs, "red", "green",bz)
self.lastloadfn = fn
print("loaded obses")

wss = workspaces(wn)
pg = playground(wn)
wb = workbench(wn)
wspg = workspace("playground", pg, wss)
wswb = workspace("workbench", wb, wss)
print("playg ",pg)
def pushnewbot(mnu):

def pushobsselect(mnu):
print("-->SETTING wn.onclick to selectobs in pushobsselect")

def dosaveplayg(mnu):

def doloadplayg(mnu):

class workbench:
"""a place to build and modify robots"""

gridcoord = ()
gridtopleft = ()

def __init__(self,scrn, bgcolor="beige"):
self.scrn = scrn
self.bgcolor = bgcolor
[]( = turtle.Turtle()
self.gridxs = []
self.gridys = []

def showbuildgrid(self):
input("lets do it again")

def showbuildgrid(self):
""" draw a grid to build robot on"""
self.vertlines = 20
self.horzlines = 32
self.linespacing = 10
workbench.gridtopleft = (-self.linespacing*self.vertlines/2, self.linespacing*self.horzlines/2), 0)
x, y = workbench.gridtopleft, y), y)
self.gridys = []"cross"),2,5)
for i in range(self.horzlines + 2):
if i == 0 or i == 1 or i == self.horzlines + 1:"blue")
else:"orange"), y)
#input("leftside i "+ str(i)), y)
if i == 0:
#input("went right side pendown")
print("pos ",
#input("x "+str(x)+ " y "+ str(y)+ " i "+ str(i))
y -= self.linespacing
x, y = self.gridtopleft
self.gridxs = []
for i in range(self.vertlines + 1):
if i == 0 or i == self.vertlines:"blue")
else:"orange"), y), -y)
x += self.linespacing
workbench.gridcoord = (self.gridxs, self.gridys)"circle"), .3, .3), 0)

def displayme(self):

wss = workspaces(wn)
pg = playground(wn)
wb = workbench(wn)
wspg = workspace("playground", pg, wss)
wswb = workspace("workbench", wb, wss)
print("playg ",pg)

class obstacle:
"""a playground area robot cannot enter"""

def begin_obs(cls, x,y,sc=wn,p=pg):
print("begin_obs sc ", sc, " p ", p)
print("brgin_obs obstacles ", str(p.obstacles))
o = obstacle(x, y, p.scrn, p, obstacle.begin_obs)
print("obs poly ", o.poly)

def __init__(self, x, y, w, pg, newofun,bcolor="red", fcolor="green", bsize=3):
self.poly = [(x,y)]
self.scrn = w
[]( = turtle.Turtle()
self.border_color = bcolor
self.fill_color = fcolor
self.border_size = bsize
self.playg = pg
self.newfun = newofun
self.range = ()
self.rangecentere = ()
self.isselected = False
self.rotatecenter = (), self.fill_color)

def __str__(self):
rslt = "obstacle ----\n poly {0} scrn {1} tt {2} bord_clr {3} fill_clr {4} "
rslt = rslt.format(self.poly, self.scrn != None, []( != None, self.border_color, self.fill_color)
rslt += "bord_size {0} playg {1} newfun {2} range {3} isseltd {4}\n"
rslt = rslt.format(self.border_size, self.playg, self.newfun,self.range,self.isselected)
return rslt

def setpoly(self, p):
self.poly = p

def drawme(self):
first = True
print("drawme poly\n ", self.poly)
idx = 0
for v in self.poly:
x,y = v
#print("drawme idx {3} x {0} y {1} v {2}".format(x, y, v, idx))
#input("new pt"), y)
if first:
first = False
idx += 1
if self.isselected:
self.setselected(False, self.playg.seltt)
self.setselected(True, self.playg.seltt)

def drawselection(self,clr, tt):
xhi, xlo = self.range[0]
yhi, ylo = self.range[1]
tt.goto(xhi, yhi)
tt.goto(xhi, ylo)
tt.goto(xlo, ylo)
tt.goto(xlo, yhi)

def setrange(self):
xmax =-9999
xmin = 9999
ymax = -9999
ymin = 9999
for v in self.poly:
x,y = v
if x > xmax:
xmax = x
if x < xmin:
xmin = x
if y > ymax:
ymax = y
if y < ymin:
ymin = y
self.range = ((xmax, xmin), (ymax, ymin))
self.rangecenter = ((xmax+xmin)/2, (ymax+ymin)/2)
print("setrange\n range {0}\n poly {1}".format(self.range, self.poly))

def setselected(self, selected, tt):
print("setselected ---- isselected will draw",selected, " tt ", tt)
if selected:
self.drawselection("black", tt)
self.isselected = True
print("setseleced ------activeitem ", menues.lastmenu.activeitem) ,
if menues.lastmenu.activeitem != None:
mname, k = menues.lastmenu.activeitem
print("----for activeitem mname= ", mname, " k= ", k)
if mname == "Obstacles" and k == "t":
print("----setting up translate drag")
x,y = self.poly[0]
tt.goto(x, y)
print(".... tt ", tt)
self.scrn.onclick(self.doxlate, 3, False)
print("-->SETTING wn.onclick to doxlate in setselected")
print("----finished drag setup")
if mname == "Obstacles" and k == "r":
print("----setting up rotaate sel center")
self.drawselection("blue", tt)
x,y = self.rangecenter
tt.goto(x, y)
print("-->SETTING wn.onclick to None in setselected")
self.scrn.onclick(self.getrotateangle, 3, False)
self.isselected = False

def getrotateangle(self, x, y):
tt = self.playg.mkrtt
x, y = self.rotatecenter
self.drawrotateguide(x,y, 50,RotationGuideTicks,"darkblue",tt)
tt.goto(x, y)
self.scrn.onclick(self.dorotate, 3, False)

def showangle(self, x, y):
tt = self.playg.mkrtt2
cx, cy = self.rotatecenter
tt.goto(cx, cy)
tt.goto(x, y)

def dragangle(self, x,y):
tt = self.playg.mkrtt
tt2 = self.playg.mkrtt2
cx, cy = self.rotatecenter

def dorotate(self, x, y):
print("dorotate----in\n ", self),
x,y = self.playg.mkrtt.position()
cx, cy = self.rotatecenter
da = math.atan2(y-cy, x-cx)
#print("dorotate----\n da {0} x,y ({1}, {2} ) cx,cy ({3}, {4})".format(math.degrees(da),x,y,cx,cy))
newpoly = []
for t in self.poly:
ox,oy = t
dox = ox - cx
doy = oy - cy
r = ((dox**2)+(doy**2))**.5
oa = math.atan2(doy, dox)
#print("dorotate ----\noa {0} r {1}".format(math.degrees(oa), r))
pt = (cx + r*math.cos(da+oa), cy + r*math.sin(da+oa))
print("dorotate nrwpoly\n ", newpoly, " oldpoly\n ", self.poly)
self.setselected(False, self.playg.seltt)

def setrotationcenter(self, x, y):
x,y = self.snaptopolypts(x ,y)
self.rotatecenter = (x, y)
self.drawrotateguide(x,y, 50,RotationGuideTicks,"orange",self.playg.mkrtt)

def snaptopolypts(self, x, y):
"""if x, y are witnin SnapDistance to poly vertex or range center return those pts else retuirn input x, y tuple"""
newx = x
newy = y
notfound = True
for pt in self.poly:
px, py = pt
if abs(px - x) <= SnapDistance and abs(py -y) <= SnapDistance:
newx = px
newy = py
notfound = False
if notfound:
px, py = self.rangecenter
if abs(px - x) <= SnapDistance and abs(py -y) <= SnapDistance:
newx = px
newy = py
return (newx, newy)

def doxlate(self, x, y):
print("doxlate----in ", self),
x,y = self.playg.seltt.position()
cx, cy = self.poly[0]
dx = x - cx
dy = y - cy
newpoly = []
for t in self.poly:
pt = (t[0]+dx, t[1]+dy)

def drawrotateguide(self, x, y, r, p, clr, t):
""" draw circle at x, y radius r with p tick marks using turtke t"""
print("drawrotateguide ---- x {0} y {1} clr {2}".format(x, y,clr))
for i in range(p):
if i%(p/4) == 0:

def endp(self, x, y):
print("endp enter x {0} y {1} poly {2}".format(x,y,self.poly))
x,y = self.poly[0],y)
idx = 0
for o in self.playg.obstacles:
print("obs["+ str(idx) +"]", o)
idx += 1
#print("playg", len(self.playg.obstacles), self.playg)
print("-->SETTING wn.onclick to ", self.newfun, " s in pushobsselect")
self.scrn.onclick(None, 3, True)
print("endp exit x {0} y {1} poly {2} me {3}".format(x,y,self.poly, str(self)))

def endl(self, x,y):
print("endl enter x {0} y {1} poly {2}".format(x,y,self.poly))
a,b = self.poly[len(self.poly)-1]
while abs(c-a)>0.0001 or abs(d-b)>0.0001:
c,d =,b),y)
print("endl exit x {0} y {1} poly {2}".format(x,y,self.poly))

def drag(self,x,y):,y)
print("have x {0} and y {1} dl [2]".format(x,y,dl))
print("-->SETTING wn.onclick to None in drag")

def startobs(self, x, y):
print("startobs self {2} x {0} y {1}".format(x, y, self)),y)
print("-->SETTING wn.onclick to None in startobs")
self.scrn.onclick(self.endp, 3, False)
print("startp x {0} y {1} poly {2}".format(x,y,self.poly))

#def __str__(self):
#return "obs at {0} with {1} sides".format(self.poly[0],len(self.poly)-1)

def begin_obs(x,y,sc=wn,p=pg):
print("brgin_obs obstacles ", str(p.obstacles))
o = obstacle(x, y, sc,p, begin_obs)
print("obs poly ", o.poly)

class robot:

texttt = turtle.Turtle()

def begin_bot(cls, sc=wn,p=pg):
print("begin_bot sc ", sc, " p ", p)
print("brgin_bot obstacles ", str(p.obstacles))
name = cls.getbotname()
r = robot(p.scrn, p, robot.begin_bot, name)
#print("obs poly ", o.poly)

def getbotname(cls,):
actn = "New robot name"
prmt = "Enter your robot's name cannot be blank"
notvalid = True
while notvalid:
rn = turtle.textinput(actn, prmt)
if rn != None and rn != "":
notvalid = False
x, y = workbench.gridtopleft
rnlen = len(rn)
lbllen = len("My name is")
robot.texttt.goto(-8-rnlen*12/2, y+2)
robot.texttt.write(rn, font=("Arial", 18, "bold"))
robot.texttt.goto(8-lbllen*11/2, y+28)
robot.texttt.write("My name is", font=("Arial", 14, "normal"))
return rn


def __init__(self, w, pg, newfun, name, bodycolor="blue"):
self.scrn = w
self.playg = pg
self.newfun = newfun
[]( = name
self.bodycolor = bodycolor
self.outlinecolor = bodycolor
self.location = (0,0)
self.bodypoly = []
self.driveaxelcenter = ()
self.wheeldiam = 0
self.heading = 0
[]( = turtle.Turtle()"cross"),1,3), self.bodycolor)
self.isonplayg = False

def startbot(self):
self.scrn.onclick(self.endrb, 3, False)

def firstpt(self, x, y):
np = self.snaptobuildgrid(x, y)

def nextpt(self, x, y):
np = self.snaptobuildgrid(x, y)

def endrb(self, x, y):
self.playg.robots[[](] = self
self.scrn.onclick(None, 3, False)

def snaptobuildgrid(self, x, y):
""" return the build grid coord closest to given x, y """
xords, yords = workbench.gridcoord
lastcx = xords[0]
lastdx = 9999999
for cx in xords:
dx = abs(x-cx)
if dx < lastdx:
lastdx = dx
lastcx = cx
lastdy = 999999
for cy in yords:
dy = abs(y-cy)
if dy < lastdy:
lastdy = dy
lastcy = cy
return (lastcx, lastcy)

class dropmenu:
""" build display and get result from a drop down list """
working = None

def getdropselection(cls, topleft, width, items, returnfun, sc=wn, itemheight=15):
cls.working = dropmenu(topleft, width, itemheight, returnfunm, sc)

def __init__(self, toplrft, width, itemheight, rtnfun, scrn):
self.topleft = topleft
self.width = width
self.scrn = scrn
self.returnfun = rtnfun
self.ysteps = []
self.itemheight = itemheight
[]( = turtle.Turtle()

def showdrop(self, items):
x, ytop = self.topleft
for i in range(len(items)):, ytop), ytop-self.itemheight), ytop-self.itemheight),ytop-self.itemheight+1)[i], font=("Arial", 12, "normal"))
self.ysteps.append((ytop-1, ytop-self.itemheight+1), items[i])
ytop -= self.itemheight, ytop)

def checkclick(self,x,y):
xlo = self.topleft[0]
xhi = xlo + self.width
if x >= xlo and x <= xhi:
for yr in self.ysteps:
yhi, ylo = yr[0]
if y <= yhi and y >= ylo:

class menuitem:
""" holds each menu item
toggle; 0-= no toggle, -1 = each key event toggles between on (1) and off (-1)F"""

def __init__(self, key, desc, dsplorder, toggle, onkeyfun, onkeyprms, enfun=None, enprms=None, exfun=None, exprms=None):
msg = "menuitem {10} key {0} desc {1} order {2} tog {3} onkeyfun {4} onkeyprm {5} enfun {6} enprm {7} exfun {8} exprm {9}"
self.key = key
self.desc = desc
self.dsplorder = dsplorder
self.enfun = enfun
self.enprms = enprms
self.exfun = exfun
self.exprms = exprms
self.toggle = toggle
self.onkeyfun = onkeyfun
self.onkeyprms = onkeyprms

def __str__(self):
rslt = "menuitem: key={0} des={1} dspidx={2} toggle {3}"
rslt = rslt.format(self.key, self.desc, self.dsplorder, self.toggle)
rslt += " onkeyfun={0} onkeyprms {1} enfun {2} enprms {3} exfun={4} exprms {5} "
return rslt.format(self.onkeyfun, self.onkeyprms, self.enfun, self.enprms, self.exfun, self.exprms)

class menues:
""" menu definition mlists is dict keyed by menue name with value as dict of menuitems"""

lastmenu = None
counter = 0

def cntr(cls):
cls.counter += 1
return cls.counter -1

def __init__(self, w, wss ):
self.wn = w
self.wss = wss
[]( = turtle.Turtle()
self.mlists = {}
self.mstack = [0]
self.keyfuns = {}
self.activeitem = None
menues.lastmenu = self

def appendmenuitem(self, mnuname,mnuitem):
print("apmi mlists ", self.mlists)
print("apmi get", self.mlists.get(mnuname,{}), " mn ", mnuname)
self.mlists[mnuname] = self.mlists.get(mnuname,[{},[]])
self.mlists[mnuname][0][mnuitem.key] = mnuitem
self.mlists[mnuname][1] = self.ordermi(self.mlists[mnuname][0])

def ordermi(self, itms):
print("ordermi itms ", itms)
rslt = []
found = True
hiorder = 0
while found:
found = False
lastodr = 9999
lastk = ""
for v in itms.values():
if v.dsplorder > hiorder and v.dsplorder < lastodr:
lastodr = v.dsplorder
lastk = v.key
if lastk != "":
found = True
hiorder = lastodr
return rslt

def pushmenu(self, mnuname):
print("pushmenu ", mnuname, "mstack ", self.mstack)
if len(self.mstack) < self.mstack[0] + 2:
if self.mstack[0] > 0:
self.mstack[0] += 1
self.mstack[self.mstack[0]] = mnuname

def popmenu(self):
if self.mstack[0] > 0:
self.mstack[0] -= 1
print("popmenu mstack ", self.mstack)

def disarmkeys(self, mname):
print("disarming keys menu ", mname)
mo = self.mlists[mname][1]
for k in mo:
self.wn.onkey(None, k.lower())
self.wn.onkey(None, k.upper())

def armkeys(self, mname):
mo = self.mlists[mname][1]
msg = "\n keys set "
for k in mo:
self.wn.onkey(self.keyfuns[k][0], k.lower())
self.wn.onkey(self.keyfuns[k][1], k.upper())
msg += k + ", "
print("armed keys menu ", mname, " ordr ", mo, msg )

def atest(self):
print("atest WHY?????")

def makemenu(self, mn):
print("makemenu[", menues.cntr(), "].....", mn)
md = self.mlists[mn][0]
mo = self.mlists[mn][1]
mtxt = mn + ": "
for k in mo:
itm = "<" + k + ">" +md[k].desc + " | "
print(" mkmu k {0} toggle {1}".format(k, md[k].toggle))
if md[k].toggle == 1:
itm = itm.upper()
print(" mkmu set upper itm", itm)
mtxt += itm
print(" mkmu mn=>" + mn + "<\n mtxt=>" + mtxt + "< \n toggle ", md[k].toggle)

def showmenu():

def doonkey(self, k):
print("doonkey[", menues.cntr(), "].....k= ", k)
k = k.lower()
if self.activeitem != None:
mname, mkey = self.activeitem
print("Turning off activeitem ", self.activeitem)
self.activeitem = None
mnn = self.mstack[self.mstack[0]]
md = self.mlists[mnn][0]
mi = md[k]
print("doonkkey ----\n mi= {0}, \n mi.onkeyprms {1}".format(mi, mi.onkeyprms))
enex = mi.toggle
print(f"doonkey enex {enex} k {k}")
if enex == 0:
if mi.onkeyfun != None:
self.executefun(mi.onkeyfun, mi.onkeyprms)
if enex == -1:
if mi.enfun != None:
self.executefun(mi.enfun, mi.enprms)
mi.toggle = 1
self.activeitem = (mnn, k)
print(f"doonkey set toggle to {mi.toggle} enex {enex} k {k}")
if enex == 1:
if mi.exfun != None:
self.executefun(mi.exfun, mi.exprms)
mi.toggle = -1
self.activeitem = None
print(f"doonkey set toggle to {mi.toggle} enex {enex} k {k}")

def executefun(self, fun, prmtuple):
print("Executefun fun= {0} prms= {1}".format(fun, prmtuple))
np = len(prmtuple)
if np == 0:
if np == 1:
if np == 2:
fun(onkeyprnd[0], onkeyprnd[1])
if np == 3:
fun(onkeyprnd[0], onkeyprnd[1], onkeyprnd[2])
if np > 3:
print("<<>>executefun action function {0} has {1} prms which is > 3".format(fun, np))

"""Define Key Event Functions"""

def ke_a():

def ke_A():

def ke_b():

def ke_B():

def ke_c():

def ke_C():

def ke_d():

def ke_D():

def ke_g():

def ke_G():

def ke_l():
print("ke_l hit")

def ke_L():

def ke_n():

def ke_N():

def ke_o():

def ke_O():

def ke_p():

def ke_P():

def ke_r():

def ke_R():

def ke_s():

def ke_S():

def ke_t():
print("ke_t hit")

def ke_T():

def ke_u():

def ke_U():

def ke_w():

def ke_W():

def buildmenus(wkspss):
mnu = menues(wn, wkspss)
mi = menuitem("p", "Playground", 1, 0, mnu.pushmenu, ("Playground",), None, None)
print("mi main p ", mi)
mnu.appendmenuitem("Main", mi)
mnu.keyfuns["p"] = (ke_p, ke_P)
mi = menuitem("r", "Robots", 2, 0, mnu.pushmenu, ("Robots",), None, None)
print("mi main r ", mi)
mnu.appendmenuitem("Main", mi)
mnu.keyfuns["r"] = (ke_r, ke_R)
mi = menuitem("l", "Load what", 5, 0, mnu.pushmenu, ("Load what",), None, (), None, None)
print("mi main l ", mi)
mnu.appendmenuitem("Main", mi)
mnu.keyfuns["l"] = (ke_l, ke_L)
mi = menuitem("s", "Save what", 6, 0, mnu.pushmenu, ("Save what",), None, (), None, None)
print("mi main s ", mi)
mnu.appendmenuitem("Main", mi)
mnu.keyfuns["s"] = (ke_s, ke_S)
mi = menuitem("o", "Obstacles", 1, 0, None, ("Save what",), None, (), None, None)
print("mi ld wt o ", mi)
mnu.appendmenuitem("Load what", mi)
mnu.keyfuns["o"] = (ke_o, ke_O)
mi = menuitem("r", "Robots", 2, 0, None, ("Save what",), None, (), None, None)
print("mi ld wt r ", mi)
mnu.appendmenuitem("Load what", mi)
mnu.keyfuns["r"] = (ke_r, ke_R)
mi = menuitem("a", "All", 3, 0, None, ("Save what",), None, (), None, None)
print("mi ld wt a ", mi)
mnu.appendmenuitem("Load what", mi)
mnu.keyfuns["a"] = (ke_a, ke_A)
mi = menuitem("o", "Obstacles", 1, 0, None, ("Save what",), None, (), None, None)
print("mi ld wt o ", mi)
mnu.appendmenuitem("Save what", mi)
mnu.keyfuns["o"] = (ke_o, ke_O)
mi = menuitem("r", "Robots", 2, 0, None, ("Save what",), None, (), None, None)
print("mi ld wt r ", mi)
mnu.appendmenuitem("Save what", mi)
mnu.keyfuns["r"] = (ke_r, ke_R)
mi = menuitem("a", "All", 3, 0, None, ("Save what",), None, (), None, None)
print("mi ld wt a ", mi)
mnu.appendmenuitem("Save what", mi)
mnu.keyfuns["a"] = (ke_a, ke_A)
mi = menuitem("o", "Obstacles", 1, 0, pushobsselect, ("Obstacles",), None, None)
print("mi playg o ", mi)
mnu.appendmenuitem("Playground", mi)
mnu.keyfuns["o"] = (ke_o, ke_O)
mi = menuitem("l", "Load", 5, 0, doloadplayg, ("Playground",), None, (), None, None)
print("mi obs l ", mi)
mnu.appendmenuitem("Playground", mi)
mnu.keyfuns["l"] = (ke_l, ke_L)
mi = menuitem("s", "Save", 6, 0, dosaveplayg, ("Playground",), None, (), None, None)
print("mi obs s ", mi)
mnu.appendmenuitem("Playground", mi)
mnu.keyfuns["s"] = (ke_s, ke_S)
mi = menuitem("b", "Back", 10, 0, mnu.popmenu, (), None, None)
print("mi obs b ", mi)
mnu.appendmenuitem("Playground", mi)
mnu.appendmenuitem("Robots", mi)
mnu.appendmenuitem("Workshop", mi)
mnu.appendmenuitem("Obstacles", mi)
mnu.appendmenuitem("Garage", mi)
mnu.appendmenuitem("Load what", mi)
mnu.appendmenuitem("Save what", mi)
mnu.keyfuns["b"] = (ke_b, ke_B)
mi = menuitem("d", "Draw", 1, -1, None, (), wn.onclick, (obstacle.begin_obs,), wn.onclick, (pg.selectobs,))
print("mi obs d ", mi)
mnu.appendmenuitem("Obstacles", mi)
mnu.keyfuns["d"] = (ke_d, ke_D)
mi = menuitem("t", "Translate", 2, -1, None, (), None, (), None , ())
print("mi obs t ", mi)
mnu.appendmenuitem("Obstacles", mi)
mnu.keyfuns["t"] = (ke_t, ke_T)
mi = menuitem("r", "Rotate", 3, -1, None, (), None, (), pg.seltt.onrelease, (None,))
print("mi obs r ", mi)
mnu.appendmenuitem("Obstacles", mi)
mi = menuitem("c", "Colors", 4, 0, 'pg.colors', ())
print("mi obs c ", mi)
mnu.appendmenuitem("Obstacles", mi)
mnu.keyfuns["c"] = (ke_c, ke_C)
mi = menuitem("w", "Workshop", 1, 0, pushnewbot, ("Workshop",))
print("mi bots w ", mi)
mnu.appendmenuitem("Robots", mi)
mnu.keyfuns["w"] = (ke_w, ke_W)
mi = menuitem("g", "Garage", 2, 0, pushnewbot, ("Garage",))
print("mi bots g ", mi)
mnu.appendmenuitem("Robots", mi)
mnu.keyfuns["w"] = (ke_w, ke_W)
mi = menuitem("l", "Load", 5, 0, "doloadbots", ("Playground",), None, (), None, None)
print("mi bots l ", mi)
mnu.appendmenuitem("Garage", mi)
mnu.keyfuns["l"] = (ke_l, ke_L)
mi = menuitem("s", "Save", 6, 0, "dosavebots", ("Playground",), None, (), None, None)
print("mi bots s ", mi)
mnu.appendmenuitem("Garage", mi)
mnu.keyfuns["s"] = (ke_s, ke_S)
mi = menuitem("d", "Draw Body", 1, 0, robot.begin_bot, () )
print("mi wksh d ", mi)
mnu.appendmenuitem("Workshop", mi)
mnu.keyfuns["d"] = (ke_d, ke_D)
mi = menuitem("u", "Undo", 2, 0, None, () )
print("mi wksh u ", mi)
mnu.appendmenuitem("Workshop", mi)
mnu.keyfuns["u"] = (ke_u, ke_U)
mi = menuitem("r", "Redraw", 3, 0, None, () )
print("mi wksh r ", mi)
mnu.appendmenuitem("Workshop", mi)
mnu.keyfuns["r"] = (ke_r, ke_R)
mi = menuitem("c", "Colors", 5, 0, None, () )
print("mi wksh c ", mi)
mnu.appendmenuitem("Workshop", mi)
mnu.keyfuns["c"] = (ke_c, ke_C)
mi = menuitem("w", "Wheels", 4, 0, None, () )
print("mi wksh w ", mi)
mnu.appendmenuitem("Workshop", mi)
mnu.keyfuns["d"] = (ke_d, ke_D)
mi = menuitem("g", "Garage", 6, 0, None, () )
print("mi wksh g ", mi)
mnu.appendmenuitem("Workshop", mi)
mnu.keyfuns["g"] = (ke_g, ke_G)
mi = menuitem("p", "Playground", 1, 0, None, () )
print("mi grge p ", mi)
mnu.appendmenuitem("Garage", mi)
mnu.keyfuns["p"] = (ke_p, ke_P)
mi = menuitem("r", "Rework", 2, 0, robot.begin_bot, () )
print("mi wksh r ", mi)
mnu.appendmenuitem("Garage", mi)
mnu.keyfuns["r"] = (ke_r, ke_R)
mi = menuitem("l", "Load", 5, 0, "doloadplayg", ("Playground",), None, (), None, None)
print("mi obs l ", mi)
mnu.appendmenuitem("Garage", mi)
mnu.keyfuns["l"] = (ke_l, ke_L)
mi = menuitem("s", "Save", 6, 0, "dosaveplayg", ("Playground",), None, (), None, None)
print("mi obs s ", mi)
mnu.appendmenuitem("Garage", mi)
mnu.keyfuns["s"] = (ke_s, ke_S)
return mnu

def getfilename(default, use, sufx):
if use == "save":
actn = "Save To"
if use == "load":
actn = "Load From"
prmt = "Current file name is '" + default + "'\nLeaving filename blank will " + actn.lower() + " the current file.\nCancel will abort " + use
notvalid = True
while notvalid:
print("getting fn")
fn = turtle.textinput(actn + " Filename", prmt)
print("txtin = ",fn, "|", fn == None)
if fn == None:
return fn
if fn == "":
if default != "":
fn = default
return None
fnl = fn.split(".")
fnlen = len(fnl)
if fnlen <= 2:
if fnlen == 2:
fnl[1] = sufx
if fnlen == 1:
fn = fnl[0] + fnl[1]
notvalid = False
return fn

def strtopoly(s):
rslt = []
s = s.replace("[","")
s = s.replace("]","")
s = s.replace("),",")),,")
l = s.split("),")
print("stop l ", l)
for v in l:
print("stop v0 ", v)
v = v.replace(", (","(")
print("stop v1", v)
v = v.replace("(","")
print("stop v2", v)
v = v.replace(")","")
print("stop v3", v)
l2 = v.split(",")
print("stop l2", l2)
t = (float(l2[0]), float(l2[1]))
return rslt

def a():
print("I'm in a")

def b():
print("I'm in b")

menul = [['a', False, 'attack'], ['b', False, 'better'],["c", False, "charle"]]
tl = makemenu(menul)
menul[1][1] = True
t2 = makemenu(menul)
wn = turtle.Screen()
makescreen(wn, menul)

print("going ppayground obs {0} robots {1}".format(pg.obstacles, pg.robots))
#wss = workspaces(wn)
mn = buildmenus(wss)

print("mn.stack {0} \nmlissts {1} \nml[main][o] {2}".format(mn.mstack, mn.mlists, mn.mlists["Main"][0]))
for m in mn.mlists.keys():
print("===================Menues Loaded=====================")
#wn.onkey(ke_o, "o")
#wn.onclick(endp, 3, True)

Hum, indentation is completely mangled. Could you please retry with the correct indentation?

Hi Jean.
Tried to send you script change to have a suffix of .heif. It didn’t work. Whole email was rejected.
Here is the body of that email:

not sure what’s happening here.

I opened the email I sent you with the script.
I selected the script text
copied and pasted it into a text editor.
saved the file and executed it without a problem

I’m using chrome browser, gmail, EditPad text editor on windows 7
On the notice they sent me about the attachment not valid file suffix they said ```authorized extensions: jpg, jpeg, png, gif, heic, heif, webp

So you think if I changed the file suffix to one of these it would get through? No it won’t!
I’m suspecting they would test the content in addition to the suffix

I will attach with one of these suffixes and see if it gets through.

Do you have another email address I could send it to?

Any other suggestions on how to get it to you?


Are we talking about real email here or the Discourse server at Plz Help with this runtime error:_tkinter.TclError: item "12" doesn't exist - #5 by amayle? I suppose the latter, and you are using it through email, right?

I am new to Discourse. If indentation doesn’t work for some reason, try

Per your suggestion I have posted it on pastbin. Not sure how you access it my pastebin username is amayle the paste is untitled.

It seems strange that the discourse server doesn’t provide a method to exchange python scripts.

Yes, I was wondering if you had a regular email account I could use to attach the file to an email.

Let me know how this works.


The way works is to create a link to your code. Create a new paste with your code, copy the link that your browser shows and paste it here.

For example, here is a paste I created:

“Error, this is a private paste or is pending moderation. If this paste belongs to you, please login to Pastebin to view it.”

You possibly need to create it publicly? Without logging in?

"This page is no longer available. It has either expired, been removed by its creator, or removed by one of the Pastebin staff. ".

What am I doing wrong.? It doesn’t accept my pastes. .

Diddn’t find any simple instructions on how to paste. Can you give me the steps you use?


1 Like

Go to

Don’t log in. I don’t know how that works. Keep it simple.

Copy your code and paste it into the “New paste” area.

Click “Create new paste” in the bottom.

Copy the link that you are now on.

Share it here.

1 Like

I suspect that’s not going to work, That’s what I did on the previous attempts.

Let’s try this. Below is a link to the file in my dropbox acct, All you need to do is go to that link

let me know if this works

1 Like

It worked. – I tinkered with your script and I am pretty clueless :frowning:

1 Like

How can I help you?

Were you able to follow the steps I gave you and reproduce the error?

The idea of the program is to build a playground where robots can run around. Obstacles are things they can’t cross but have to go around.

In the obstacle Draw mode you can draw as many obstacles as you like.
When you exit the draw mode by keying “d” again or “t” or “r”, it points the screen mouse onclick event to run the playground.selectobs() function which checks to see if it’s positioned over one of the obstacles. If so it deselects any previously selected obstacle and selects the one it’s on.

Once selected it sets up the turtle to track the mouse by setting the turtle’s ondrag event to turtle goto method.

I use many turtles to control the display, When you move something you need to erase the old position and redraw it in the new position.
The turtle has a clear() method that erases everything it’s drawn from the screen. By using different turtles you can selectively erase items from the screen and redraw them in a new position.

Don’t know if this rambling is of any help, maybe you’re saying this is more than you want to take on. The program uses a lot of techniques that may not be obvious at a glance. If you choose to continue, I am happy to explain anything you like. I have over 30 years of programming experience doing operating systems, business applications, development and release systems, and more. This error threw me, It seems like possibly something is getting clobbered in the python runtime. But I don’t know where to begin to look. I don’t know your level of experience, but I would be happy to work with you and perhaps show you some new tricks while you flesh out python issues.

Yes, I could reproduce the error, but after an hour I was unable to figure it out. I’d be happy to continue trying, just running out of time for now. The soonest I could make time would be next week-end. Meanwhile, anyone should feel free to step in!

You explanations help somewhat. I think a step towards understanding the bug would be to reduce the script to a minimum, e.g. just one playground, pre-drawn obstacles. That is likely to point you to the problem, and even if it doesn’t, it will be much easier to figure it out afterwards.

On a general stance, the turtle module is really intended for education and you may be better off with something like pygame.

Thank you for your interest and efforts so far… You are absolutely right the turtle is NOT the way to build this program.
When posting this request I was hoping someone with deep experience in the runtime would say I’ve seen this before, and had a clue of what to look for.

At this point I believe I have some bad syntax in the script the compiler is not catching. Your suggestion of simplifying the script makes sense. I would do this by commenting out chunks of code and see if that cures the problem.

If you would like to proceed down that path, and maybe discover a compiler bug, i would be happy to work with you. If you see any value in understanding more about the structure of the program adding to your bag of tricks. That would be cool. Let me know your thoughts

I have moved on to a pygame version, and have no more need for this particular script working. But it would be nice to know how not to screw things up.

The following are some random thoughts of an old man that may or may not be interesting to you on how I got to this project

There are lots of chunks of code not used in getting to the error. The robot, workshop objects. Commenting them out may cause some undefines in the menu build but the offending line can be committed out
The more I think about it, there is probably some typo in my script screwing up something, but the compiler is not catching it.
From the last time it was working I’ve added a lot of code, though none related to this selection process.

I just remembered something that happened. In the workshop module I build a grid on which to design a robot. It draws a series of horizontal and vertical lines. The first and last lines are recognized in the respective for loops and formatted with wider and different colors.

When I tested it the first horizontal line was not drawn at all, even though debugging print statements verified the code was executing the correct instructions, but the turtle was not drawing this first line, all the other lines were drawn correctly.
This was not correct behavior for the turtle. Havinng no ideas what was causing this behavior, and wanting to move on I found a workaround by drawing that first line twice.
This was a first sign something was wrong in the runtime. My guess is that I have some bad syntax somewhere the complier is not catching it but its messing up the run time.

Let me share the story of how I got here:

Several factors got me into this:

  1. for yearsm nay decades, I have wanted to build a robot (the physical kind)
  2. I was intrigued by the raspberry pi 4micro computer
    it supports two 4k hdmi displays
    the 8gb version is $65, by the time you add a case, poweresupply, sd card you can get to the mid $100 range.
    This card is used by many in robot projects
    it runs linux, and python is its favorite robotics language, I have wanted to get back to a unix type environment. This looked good.
  3. My goddaughter loved some coding they did in middle school and wanted to learn more
    A number of summers ago I tutored a couple middle school boys in programming. They wanted to build games.
    I used logo to introduce them to programming, then we advanced to pygame to build a game. At the time I was not aware of the python turtle.
    We built a battleship game in pygame
  4. In december, I purchased the r pi 4.
    I realized building a physical robot was not practical in my current situation (no place for a real workshop)
    I realized a software autonomous robot with the ability to use its sensors to navigate an obstacle filled environment would be an interesting project
    My intention was to use pygame to build it.
    As an aside, I built a crude version of such a robot using AWK. a text file defined the robots way points and fences across those paths the robot would have to figure out how to get around. The useful output was a csv file that Iloaded into excel and plotted many data series on a x,y chart to display its requested path and the one it actually followed. The routines developed here will be useful in my pygame robot.
    If you are not familiar with AWK, I suggest you discover it. It’s text processing, very simple to learn and understand. I have used it to build compilers, scripts on windows, chopping up huge log files into free text editor workable sizes. Your imagination is the only limit
  5. I started teaching my goddaughter python. The tutorial we found soon got us into the turtle. So I started playing with it.
  6. I started developing the program with turtles, thinking maybe she could understand what I was doing. That soon fell apart as my design became more obscure without having its model in mind. I am abandoning the turtle version and converting it to pygame.

If you got this far, Thanks again