Lines Matching +full:- +full:- +full:no +full:- +full:self +full:- +full:update
3 # Version 1.1b - 4. 5. 2009
5 # Copyright (C) 2006 - 2010 Gregor Lingl
8 # This software is provided 'as-is', without any express or implied
9 # warranty. In no event will the authors be held liable for any damages
30 Imagine a robotic turtle starting at (0, 0) in the x-y plane. After an ``import turtle``, give it
31 the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
33 command turtle.right(25), and it rotates in-place 25 degrees clockwise.
38 ----- turtle.py
47 the -n switch.
51 - Better animation of the turtle movements, especially of turning the
55 - Different turtle shapes, gif-images as turtle shapes, user defined
60 - Fine control over turtle movement and screen updates via delay(),
63 - Aliases for the most commonly used commands, like fd for forward etc.,
69 - Turtles now have an undo()-method with configurable undo-buffer.
71 - Some simple commands/methods for creating event driven programs
72 (mouse-, key-, timer-events). Especially useful for programming games.
74 - A scrollable Canvas class. The default scrollable Canvas can be
77 - A TurtleScreen class with methods controlling background color or
81 - There is a method, setworldcoordinates(), to install a user defined
82 coordinate-system for the TurtleScreen.
84 - The implementation uses a 2-vector class named Vec2D, derived from tuple.
88 - Appearance of the TurtleScreen and the Turtles at startup/import can be
92 - If configured appropriately the module reads in docstrings from a docstring
103 _ver = "turtle 1.1b- - for Python 3.1 - 4. 5. 2009"
126 'setworldcoordinates', 'textinput', 'title', 'tracer', 'turtles', 'update',
173 """Convert content of config-file into dictionary."""
184 print("Bad line in config-file %s:\n%s" % (filename,line))
202 """Read config-files, change configuration-dict accordingly.
205 read it from there. If this contains an importconfig-value,
207 turtle.cfg and read it from the import-directory, where
209 Update configuration dictionary first according to config-file,
210 in the import directory, then according to config-file in the
212 If no config-file is found, the default configuration is used.
228 _CFG.update(cfgdict2)
229 _CFG.update(cfgdict1)
234 print ("No configfile read, reason unknown")
245 a-b vector subtraction
253 def __add__(self, other): argument
254 return Vec2D(self[0]+other[0], self[1]+other[1])
255 def __mul__(self, other): argument
257 return self[0]*other[0]+self[1]*other[1]
258 return Vec2D(self[0]*other, self[1]*other)
259 def __rmul__(self, other): argument
261 return Vec2D(self[0]*other, self[1]*other)
263 def __sub__(self, other): argument
264 return Vec2D(self[0]-other[0], self[1]-other[1])
265 def __neg__(self): argument
266 return Vec2D(-self[0], -self[1])
267 def __abs__(self): argument
268 return math.hypot(*self)
269 def rotate(self, angle): argument
270 """rotate self counterclockwise by angle
272 perp = Vec2D(-self[1], self[0])
275 return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s)
276 def __getnewargs__(self): argument
277 return (self[0], self[1])
278 def __repr__(self): argument
279 return "(%.2f,%.2f)" % self
283 ### From here up to line : Tkinter - Interface for turtle.py ###
287 ## helper functions for Scrolled Canvas, to forward Canvas-methods
307 'def %(method)s(self, *args, **kw): return ' +
308 'self.%(attribute)s.%(method)s(*args, **kw)')
317 if ex[:1] == '_' or ex[-1:] == '_' or ex in exclude or ex in mfc:
337 def __init__(self, master, width=500, height=350, argument
339 TK.Frame.__init__(self, master, width=width, height=height)
340 self._rootwindow = self.winfo_toplevel()
341 self.width, self.height = width, height
342 self.canvwidth, self.canvheight = canvwidth, canvheight
343 self.bg = "white"
344 self._canvas = TK.Canvas(master, width=width, height=height,
345 bg=self.bg, relief=TK.SUNKEN, borderwidth=2)
346 self.hscroll = TK.Scrollbar(master, command=self._canvas.xview,
348 self.vscroll = TK.Scrollbar(master, command=self._canvas.yview)
349 self._canvas.configure(xscrollcommand=self.hscroll.set,
350 yscrollcommand=self.vscroll.set)
351 self.rowconfigure(0, weight=1, minsize=0)
352 self.columnconfigure(0, weight=1, minsize=0)
353 self._canvas.grid(padx=1, in_ = self, pady=1, row=0,
355 self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
357 self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
359 self.reset()
360 self._rootwindow.bind('<Configure>', self.onResize)
362 def reset(self, canvwidth=None, canvheight=None, bg = None): argument
365 self.canvwidth = canvwidth
367 self.canvheight = canvheight
369 self.bg = bg
370 self._canvas.config(bg=bg,
371 scrollregion=(-self.canvwidth//2, -self.canvheight//2,
372 self.canvwidth//2, self.canvheight//2))
373 self._canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) /
374 self.canvwidth)
375 self._canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) /
376 self.canvheight)
377 self.adjustScrolls()
380 def adjustScrolls(self): argument
381 """ Adjust scrollbars according to window- and canvas-size.
383 cwidth = self._canvas.winfo_width()
384 cheight = self._canvas.winfo_height()
385 self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth)
386 self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight)
387 if cwidth < self.canvwidth or cheight < self.canvheight:
388 self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
390 self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
393 self.hscroll.grid_forget()
394 self.vscroll.grid_forget()
396 def onResize(self, event): argument
397 """self-explanatory"""
398 self.adjustScrolls()
400 def bbox(self, *args): argument
403 return self._canvas.bbox(*args)
405 def cget(self, *args, **kwargs): argument
408 return self._canvas.cget(*args, **kwargs)
410 def config(self, *args, **kwargs): argument
413 self._canvas.config(*args, **kwargs)
415 def bind(self, *args, **kwargs): argument
418 self._canvas.bind(*args, **kwargs)
420 def unbind(self, *args, **kwargs): argument
423 self._canvas.unbind(*args, **kwargs)
425 def focus_force(self): argument
428 self._canvas.focus_force()
435 def __init__(self): argument
436 TK.Tk.__init__(self)
438 def setupcanvas(self, width, height, cwidth, cheight): argument
439 self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight)
440 self._canvas.pack(expand=1, fill="both")
442 def _getcanvas(self): argument
443 return self._canvas
445 def set_geometry(self, width, height, startx, starty): argument
446 self.geometry("%dx%d%+d%+d"%(width, height, startx, starty))
448 def ondestroy(self, destroy): argument
449 self.wm_protocol("WM_DELETE_WINDOW", destroy)
451 def win_width(self): argument
452 return self.winfo_screenwidth()
454 def win_height(self): argument
455 return self.winfo_screenheight()
468 def _blankimage(self): argument
471 img = TK.PhotoImage(width=1, height=1, master=self.cv)
475 def _image(self, filename): argument
477 imagedata from a gif-file named filename.
479 return TK.PhotoImage(file=filename, master=self.cv)
481 def __init__(self, cv): argument
482 self.cv = cv
484 w = self.cv.canvwidth
485 h = self.cv.canvheight
487 w = int(self.cv.cget("width"))
488 h = int(self.cv.cget("height"))
489 self.cv.config(scrollregion = (-w//2, -h//2, w//2, h//2 ))
490 self.canvwidth = w
491 self.canvheight = h
492 self.xscale = self.yscale = 1.0
494 def _createpoly(self): argument
495 """Create an invisible polygon item on canvas self.cv)
497 return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill="", outline="")
499 def _drawpoly(self, polyitem, coordlist, fill=None, argument
512 cl.append(x * self.xscale)
513 cl.append(-y * self.yscale)
514 self.cv.coords(polyitem, *cl)
516 self.cv.itemconfigure(polyitem, fill=fill)
518 self.cv.itemconfigure(polyitem, outline=outline)
520 self.cv.itemconfigure(polyitem, width=width)
522 self.cv.tag_raise(polyitem)
524 def _createline(self): argument
525 """Create an invisible line item on canvas self.cv)
527 return self.cv.create_line(0, 0, 0, 0, fill="", width=2,
530 def _drawline(self, lineitem, coordlist=None, argument
543 cl.append(x * self.xscale)
544 cl.append(-y * self.yscale)
545 self.cv.coords(lineitem, *cl)
547 self.cv.itemconfigure(lineitem, fill=fill)
549 self.cv.itemconfigure(lineitem, width=width)
551 self.cv.tag_raise(lineitem)
553 def _delete(self, item): argument
557 self.cv.delete(item)
559 def _update(self): argument
562 self.cv.update()
564 def _delay(self, delay): argument
566 self.cv.after(delay)
568 def _iscolorstring(self, color): argument
572 rgb = self.cv.winfo_rgb(color)
578 def _bgcolor(self, color=None): argument
582 self.cv.config(bg = color)
583 self._update()
585 return self.cv.cget("bg")
587 def _write(self, pos, txt, align, font, pencolor): argument
590 Return text item and x-coord of right bottom corner
593 x = x * self.xscale
594 y = y * self.yscale
596 item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align],
598 x0, y0, x1, y1 = self.cv.bbox(item)
599 return item, x1-1
601 ## def _dot(self, pos, size, color):
604 def _onclick(self, item, fun, num=1, add=None): argument
605 """Bind fun to mouse-click event on turtle.
608 num, the number of the mouse-button defaults to 1
611 self.cv.tag_unbind(item, "<Button-%s>" % num)
614 x, y = (self.cv.canvasx(event.x)/self.xscale,
615 -self.cv.canvasy(event.y)/self.yscale)
617 self.cv.tag_bind(item, "<Button-%s>" % num, eventfun, add)
619 def _onrelease(self, item, fun, num=1, add=None): argument
620 """Bind fun to mouse-button-release event on turtle.
623 num, the number of the mouse-button defaults to 1
625 If a turtle is clicked, first _onclick-event will be performed,
626 then _onscreensclick-event.
629 self.cv.tag_unbind(item, "<Button%s-ButtonRelease>" % num)
632 x, y = (self.cv.canvasx(event.x)/self.xscale,
633 -self.cv.canvasy(event.y)/self.yscale)
635 self.cv.tag_bind(item, "<Button%s-ButtonRelease>" % num,
638 def _ondrag(self, item, fun, num=1, add=None): argument
639 """Bind fun to mouse-move-event (with pressed mouse button) on turtle.
642 num, the number of the mouse-button defaults to 1
644 Every sequence of mouse-move-events on a turtle is preceded by a
645 mouse-click event on that turtle.
648 self.cv.tag_unbind(item, "<Button%s-Motion>" % num)
652 x, y = (self.cv.canvasx(event.x)/self.xscale,
653 -self.cv.canvasy(event.y)/self.yscale)
657 self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
659 def _onscreenclick(self, fun, num=1, add=None): argument
660 """Bind fun to mouse-click event on canvas.
663 num, the number of the mouse-button defaults to 1
665 If a turtle is clicked, first _onclick-event will be performed,
666 then _onscreensclick-event.
669 self.cv.unbind("<Button-%s>" % num)
672 x, y = (self.cv.canvasx(event.x)/self.xscale,
673 -self.cv.canvasy(event.y)/self.yscale)
675 self.cv.bind("<Button-%s>" % num, eventfun, add)
677 def _onkeyrelease(self, fun, key): argument
678 """Bind fun to key-release event of key.
682 self.cv.unbind("<KeyRelease-%s>" % key, None)
686 self.cv.bind("<KeyRelease-%s>" % key, eventfun)
688 def _onkeypress(self, fun, key=None): argument
689 """If key is given, bind fun to key-press event of key.
690 Otherwise bind fun to any key-press.
695 self.cv.unbind("<KeyPress>", None)
697 self.cv.unbind("<KeyPress-%s>" % key, None)
702 self.cv.bind("<KeyPress>", eventfun)
704 self.cv.bind("<KeyPress-%s>" % key, eventfun)
706 def _listen(self): argument
707 """Set focus on canvas (in order to collect key-events)
709 self.cv.focus_force()
711 def _ontimer(self, fun, t): argument
715 self.cv.after_idle(fun)
717 self.cv.after(t, fun)
719 def _createimage(self, image): argument
722 return self.cv.create_image(0, 0, image=image)
724 def _drawimage(self, item, pos, image): argument
729 self.cv.coords(item, (x * self.xscale, -y * self.yscale))
730 self.cv.itemconfig(item, image=image)
732 def _setbgpic(self, item, image): argument
737 self.cv.itemconfig(item, image=image)
738 self.cv.tag_lower(item)
740 def _type(self, item): argument
744 return self.cv.type(item)
746 def _pointlist(self, item): argument
747 """returns list of coordinate-pairs of points of item
751 [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982),
754 cl = self.cv.coords(item)
755 pl = [(cl[i], -cl[i+1]) for i in range(0, len(cl), 2)]
758 def _setscrollregion(self, srx1, sry1, srx2, sry2): argument
759 self.cv.config(scrollregion=(srx1, sry1, srx2, sry2))
761 def _rescale(self, xscalefactor, yscalefactor): argument
762 items = self.cv.find_all()
764 coordinates = list(self.cv.coords(item))
771 self.cv.coords(item, *newcoordlist)
773 def _resize(self, canvwidth=None, canvheight=None, bg=None): argument
778 if not isinstance(self.cv, ScrolledCanvas):
779 return self.canvwidth, self.canvheight
781 return self.cv.canvwidth, self.cv.canvheight
783 self.canvwidth = canvwidth
785 self.canvheight = canvheight
786 self.cv.reset(canvwidth, canvheight, bg)
788 def _window_size(self): argument
791 width = self.cv.winfo_width()
793 width = self.cv['width']
794 height = self.cv.winfo_height()
796 height = self.cv['height']
799 def mainloop(self): argument
800 """Starts event loop - calling Tkinter's mainloop function.
802 No argument.
805 Must NOT be used if a script is run from within IDLE in -n mode
806 (No subprocess) - for interactive use of turtle graphics.
812 self.cv.tk.mainloop()
814 def textinput(self, title, prompt): argument
827 return simpledialog.askstring(title, prompt, parent=self.cv)
829 def numinput(self, title, prompt, default=None, minval=None, maxval=None): argument
849 parent=self.cv)
853 ### End of Tkinter - interface ###
858 """Will be raised in TurtleScreen.update, if _RUNNING becomes False.
861 Main purpose: use in the Demo-Viewer turtle.Demo.py.
875 attribute _data is - depending on _type a poygon-tuple,
878 def __init__(self, type_, data=None): argument
879 self._type = type_
891 raise TurtleGraphicsError("There is no shape type %s" % type_)
892 self._data = data
894 def addcomponent(self, poly, fill, outline=None): argument
902 -- s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue")
905 >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
910 if self._type != "compound":
912 % self._type)
915 self._data.append([poly, fill, outline])
920 def __init__(self, bufsize=10): argument
921 self.bufsize = bufsize
922 self.buffer = [[None]] * bufsize
923 self.ptr = -1
924 self.cumulate = False
925 def reset(self, bufsize=None): argument
927 for i in range(self.bufsize):
928 self.buffer[i] = [None]
930 self.bufsize = bufsize
931 self.buffer = [[None]] * bufsize
932 self.ptr = -1
933 def push(self, item): argument
934 if self.bufsize > 0:
935 if not self.cumulate:
936 self.ptr = (self.ptr + 1) % self.bufsize
937 self.buffer[self.ptr] = item
939 self.buffer[self.ptr].append(item)
940 def pop(self): argument
941 if self.bufsize > 0:
942 item = self.buffer[self.ptr]
946 self.buffer[self.ptr] = [None]
947 self.ptr = (self.ptr - 1) % self.bufsize
949 def nr_of_items(self): argument
950 return self.bufsize - self.buffer.count([None])
951 def __repr__(self): argument
952 return str(self.buffer) + " " + str(self.ptr)
960 upon components of the underlying graphics toolkit -
965 def __init__(self, cv, mode=_CFG["mode"], argument
967 TurtleScreenBase.__init__(self, cv)
969 self._shapes = {
970 "arrow" : Shape("polygon", ((-10,0), (10,0), (0,10))),
971 "turtle" : Shape("polygon", ((0,16), (-2,14), (-1,10), (-4,7),
972 (-7,9), (-9,8), (-6,5), (-7,1), (-5,-3), (-8,-6),
973 (-6,-8), (-4,-5), (0,-7), (4,-5), (6,-8), (8,-6),
974 (5,-3), (7,1), (6,5), (9,8), (7,9), (4,7), (1,10),
977 (5.88,8.09), (3.09,9.51), (0,10), (-3.09,9.51),
978 (-5.88,8.09), (-8.09,5.88), (-9.51,3.09), (-10,0),
979 (-9.51,-3.09), (-8.09,-5.88), (-5.88,-8.09),
980 (-3.09,-9.51), (-0.00,-10.00), (3.09,-9.51),
981 (5.88,-8.09), (8.09,-5.88), (9.51,-3.09))),
982 "square" : Shape("polygon", ((10,-10), (10,10), (-10,10),
983 (-10,-10))),
984 "triangle" : Shape("polygon", ((10,-5.77), (0,11.55),
985 (-10,-5.77))),
986 "classic": Shape("polygon", ((0,0),(-5,-9),(0,-7),(5,-9))),
987 "blank" : Shape("image", self._blankimage())
990 self._bgpics = {"nopic" : ""}
992 self._mode = mode
993 self._delayvalue = delay
994 self._colormode = _CFG["colormode"]
995 self._keys = []
996 self.clear()
1002 rootwindow.call('wm', 'attributes', '.', '-topmost', '1')
1003 rootwindow.call('wm', 'attributes', '.', '-topmost', '0')
1005 def clear(self): argument
1008 No argument.
1011 no backgroundimage, no eventbindings and tracing on.
1018 self._delayvalue = _CFG["delay"]
1019 self._colormode = _CFG["colormode"]
1020 self._delete("all")
1021 self._bgpic = self._createimage("")
1022 self._bgpicname = "nopic"
1023 self._tracing = 1
1024 self._updatecounter = 0
1025 self._turtles = []
1026 self.bgcolor("white")
1028 self.onclick(None, btn)
1029 self.onkeypress(None)
1030 for key in self._keys[:]:
1031 self.onkey(None, key)
1032 self.onkeypress(None, key)
1035 def mode(self, mode=None): argument
1036 """Set turtle-mode ('standard', 'logo' or 'world') and perform reset.
1039 mode -- one of the strings 'standard', 'logo' or 'world'
1042 Mode 'logo' is compatible with most Logo-Turtle-Graphics.
1044 this mode angles appear distorted if x/y unit-ratio doesn't equal 1.
1048 ------------|-------------------------|-------------------
1058 return self._mode
1061 raise TurtleGraphicsError("No turtle-graphics-mode %s" % mode)
1062 self._mode = mode
1064 self._setscrollregion(-self.canvwidth//2, -self.canvheight//2,
1065 self.canvwidth//2, self.canvheight//2)
1066 self.xscale = self.yscale = 1.0
1067 self.reset()
1069 def setworldcoordinates(self, llx, lly, urx, ury): argument
1070 """Set up a user defined coordinate-system.
1073 llx -- a number, x-coordinate of lower left corner of canvas
1074 lly -- a number, y-coordinate of lower left corner of canvas
1075 urx -- a number, x-coordinate of upper right corner of canvas
1076 ury -- a number, y-coordinate of upper right corner of canvas
1078 Set up user coodinat-system and switch to mode 'world' if necessary.
1082 But ATTENTION: in user-defined coordinatesystems angles may appear
1086 >>> screen.setworldcoordinates(-10,-0.5,50,1.5)
1091 if self.mode() != "world":
1092 self.mode("world")
1093 xspan = float(urx - llx)
1094 yspan = float(ury - lly)
1095 wx, wy = self._window_size()
1096 self.screensize(wx-20, wy-20)
1097 oldxscale, oldyscale = self.xscale, self.yscale
1098 self.xscale = self.canvwidth / xspan
1099 self.yscale = self.canvheight / yspan
1100 srx1 = llx * self.xscale
1101 sry1 = -ury * self.yscale
1102 srx2 = self.canvwidth + srx1
1103 sry2 = self.canvheight + sry1
1104 self._setscrollregion(srx1, sry1, srx2, sry2)
1105 self._rescale(self.xscale/oldxscale, self.yscale/oldyscale)
1106 self.update()
1108 def register_shape(self, name, shape=None): argument
1112 (1) name is the name of a gif-file and shape is None.
1114 !! Image-shapes DO NOT rotate when turning the turtle,
1125 --or: register_shape("tri", ((0,0), (10,10), (-10,10)))
1128 >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3)))
1134 shape = Shape("image", self._image(name))
1140 ## else shape assumed to be Shape-instance
1141 self._shapes[name] = shape
1143 def _colorstr(self, color): argument
1156 if self._iscolorstring(color) or color == "":
1164 if self._colormode == 1.0:
1170 def _color(self, cstr): argument
1179 return tuple(c * self._colormode/255 for c in cl)
1181 def colormode(self, cmode=None): argument
1185 cmode -- one of the values 1.0 or 255
1196 return self._colormode
1198 self._colormode = float(cmode)
1200 self._colormode = int(cmode)
1202 def reset(self): argument
1205 No argument.
1210 for turtle in self._turtles:
1211 turtle._setmode(self._mode)
1214 def turtles(self): argument
1221 return self._turtles
1223 def bgcolor(self, *args): argument
1227 in the range 0..colormode or a 3-tuple of such numbers.
1238 color = self._colorstr(args)
1241 color = self._bgcolor(color)
1243 color = self._color(color)
1246 def tracer(self, n=None, delay=None): argument
1247 """Turns turtle animation on/off and set delay for update drawings.
1250 n -- nonnegative integer
1251 delay -- nonnegative integer
1253 If n is given, only each n-th regular screen update is really performed.
1266 return self._tracing
1267 self._tracing = int(n)
1268 self._updatecounter = 0
1270 self._delayvalue = int(delay)
1271 if self._tracing:
1272 self.update()
1274 def delay(self, delay=None): argument
1278 delay -- positive integer
1286 return self._delayvalue
1287 self._delayvalue = int(delay)
1289 def _incrementudc(self): argument
1290 """Increment update counter."""
1294 if self._tracing > 0:
1295 self._updatecounter += 1
1296 self._updatecounter %= self._tracing
1298 def update(self): member in TurtleScreen
1299 """Perform a TurtleScreen update.
1301 tracing = self._tracing
1302 self._tracing = True
1303 for t in self.turtles():
1306 self._tracing = tracing
1307 self._update()
1309 def window_width(self): argument
1316 return self._window_size()[0]
1318 def window_height(self): argument
1325 return self._window_size()[1]
1327 def getcanvas(self): argument
1330 No argument.
1337 return self.cv
1339 def getshapes(self): argument
1342 No argument.
1348 return sorted(self._shapes.keys())
1350 def onclick(self, fun, btn=1, add=None): argument
1351 """Bind fun to mouse-click event on canvas.
1354 fun -- a function with two arguments, the coordinates of the
1356 btn -- the number of the mouse-button, defaults to 1
1365 self._onscreenclick(fun, btn, add)
1367 def onkey(self, fun, key): argument
1368 """Bind fun to key-release event of key.
1371 fun -- a function with no arguments
1372 key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
1374 In order to be able to register key-events, TurtleScreen
1387 the up-arrow key, consequently drawing a hexagon
1391 if key in self._keys:
1392 self._keys.remove(key)
1393 elif key not in self._keys:
1394 self._keys.append(key)
1395 self._onkeyrelease(fun, key)
1397 def onkeypress(self, fun, key=None): argument
1398 """Bind fun to key-press event of key if key is given,
1399 or to any key-press-event if no key is given.
1402 fun -- a function with no arguments
1403 key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
1405 In order to be able to register key-events, TurtleScreen
1419 the up-arrow key, or by keeping pressed the up-arrow key.
1423 if key in self._keys:
1424 self._keys.remove(key)
1425 elif key is not None and key not in self._keys:
1426 self._keys.append(key)
1427 self._onkeypress(fun, key)
1429 def listen(self, xdummy=None, ydummy=None): argument
1430 """Set focus on TurtleScreen (in order to collect key-events)
1432 No arguments.
1439 self._listen()
1441 def ontimer(self, fun, t=0): argument
1445 fun -- a function with no arguments.
1446 t -- a number >= 0
1460 self._ontimer(fun, t)
1462 def bgpic(self, picname=None): argument
1466 picname -- a string, name of a gif-file or "nopic".
1480 return self._bgpicname
1481 if picname not in self._bgpics:
1482 self._bgpics[picname] = self._image(picname)
1483 self._setbgpic(self._bgpic, self._bgpics[picname])
1484 self._bgpicname = picname
1486 def screensize(self, canvwidth=None, canvheight=None, bg=None): argument
1490 canvwidth -- positive integer, new width of canvas in pixels
1491 canvheight -- positive integer, new height of canvas in pixels
1492 bg -- colorstring or color-tuple, new backgroundcolor
1493 If no arguments are given, return current (canvaswidth, canvasheight)
1501 >>> # e.g. to search for an erroneously escaped turtle ;-)
1503 return self._resize(canvwidth, canvheight, bg)
1523 def __init__(self, mode=DEFAULT_MODE): argument
1524 self._angleOffset = self.DEFAULT_ANGLEOFFSET
1525 self._angleOrient = self.DEFAULT_ANGLEORIENT
1526 self._mode = mode
1527 self.undobuffer = None
1528 self.degrees()
1529 self._mode = None
1530 self._setmode(mode)
1531 TNavigator.reset(self)
1533 def reset(self): argument
1538 self._position = Vec2D(0.0, 0.0)
1539 self._orient = TNavigator.START_ORIENTATION[self._mode]
1541 def _setmode(self, mode=None): argument
1542 """Set turtle-mode to 'standard', 'world' or 'logo'.
1545 return self._mode
1548 self._mode = mode
1550 self._angleOffset = 0
1551 self._angleOrient = 1
1553 self._angleOffset = self._fullcircle/4.
1554 self._angleOrient = -1
1556 def _setDegreesPerAU(self, fullcircle): argument
1558 self._fullcircle = fullcircle
1559 self._degreesPerAU = 360/fullcircle
1560 if self._mode == "standard":
1561 self._angleOffset = 0
1563 self._angleOffset = fullcircle/4.
1565 def degrees(self, fullcircle=360.0): argument
1569 fullcircle - a number
1581 grade, or gradian and equals 1/100-th of the right angle.)
1587 self._setDegreesPerAU(fullcircle)
1589 def radians(self): argument
1592 No arguments.
1601 self._setDegreesPerAU(math.tau)
1603 def _go(self, distance): argument
1605 ende = self._position + self._orient * distance
1606 self._goto(ende)
1608 def _rotate(self, angle): argument
1610 angle *= self._degreesPerAU
1611 self._orient = self._orient.rotate(angle)
1613 def _goto(self, end): argument
1615 self._position = end
1617 def forward(self, distance): argument
1623 distance -- a number (integer or float)
1634 >>> turtle.forward(-75)
1636 (-50.00,0.00)
1638 self._go(distance)
1640 def back(self, distance): argument
1646 distance -- a number
1656 (-30.00, 0.00)
1658 self._go(-distance)
1660 def right(self, angle): argument
1666 angle -- a number (integer or float)
1679 self._rotate(-angle)
1681 def left(self, angle): argument
1687 angle -- a number (integer or float)
1700 self._rotate(angle)
1702 def pos(self): argument
1703 """Return the turtle's current location (x,y), as a Vec2D-vector.
1707 No arguments.
1713 return self._position
1715 def xcor(self): argument
1718 No arguments.
1727 return self._position[0]
1729 def ycor(self): argument
1731 ---
1732 No arguments.
1741 return self._position[1]
1744 def goto(self, x, y=None): argument
1750 x -- a number or a pair/vector of numbers
1751 y -- a number None
1754 --or: goto((x, y)) # a pair (tuple) of coordinates
1755 --or: goto(vec) # e.g. as returned by pos()
1775 self._goto(Vec2D(*x))
1777 self._goto(Vec2D(x, y))
1779 def home(self): argument
1780 """Move turtle to the origin - coordinates (0,0).
1782 No arguments.
1784 Move turtle to the origin - coordinates (0,0) and set its
1785 heading to its start-orientation (which depends on mode).
1790 self.goto(0, 0)
1791 self.setheading(0)
1793 def setx(self, x): argument
1797 x -- a number (integer or float)
1809 self._goto(Vec2D(x, self._position[1]))
1811 def sety(self, y): argument
1815 y -- a number (integer or float)
1823 >>> turtle.sety(-10)
1825 (0.00, -10.00)
1827 self._goto(Vec2D(self._position[0], y))
1829 def distance(self, x, y=None): argument
1833 x -- a number or a pair/vector of numbers or a turtle instance
1834 y -- a number None None
1837 --or: distance((x, y)) # a pair (tuple) of coordinates
1838 --or: distance(vec) # e.g. as returned by pos()
1839 --or: distance(mypen) # where mypen is another turtle
1859 return abs(pos - self._position)
1861 def towards(self, x, y=None): argument
1865 x -- a number or a pair/vector of numbers or a turtle instance
1866 y -- a number None None
1869 --or: distance((x, y)) # a pair (tuple) of coordinates
1870 --or: distance(vec) # e.g. as returned by pos()
1871 --or: distance(mypen) # where mypen is another turtle
1873 Return the angle, between the line from turtle-position to position
1875 modes - "standard" or "logo")
1891 x, y = pos - self._position
1893 result /= self._degreesPerAU
1894 return (self._angleOffset + self._angleOrient*result) % self._fullcircle
1896 def heading(self): argument
1899 No arguments.
1906 x, y = self._orient
1908 result /= self._degreesPerAU
1909 return (self._angleOffset + self._angleOrient*result) % self._fullcircle
1911 def setheading(self, to_angle): argument
1917 to_angle -- a number (integer or float)
1922 standard - mode: logo-mode:
1923 -------------------|--------------------
1924 0 - east 0 - north
1925 90 - north 90 - east
1926 180 - west 180 - south
1927 270 - south 270 - west
1934 angle = (to_angle - self.heading())*self._angleOrient
1935 full = self._fullcircle
1936 angle = (angle+full/2.)%full - full/2.
1937 self._rotate(angle)
1939 def circle(self, radius, extent = None, steps = None): argument
1943 radius -- a number
1944 extent (optional) -- a number
1945 steps (optional) -- an integer
1948 of the turtle; extent - an angle - determines which part of the
1961 --or: circle(radius, extent) # arc
1962 --or: circle(radius, extent, steps)
1963 --or: circle(radius, steps=6) # 6-sided polygon
1969 if self.undobuffer:
1970 self.undobuffer.push(["seq"])
1971 self.undobuffer.cumulate = True
1972 speed = self.speed()
1974 extent = self._fullcircle
1976 frac = abs(extent)/self._fullcircle
1980 l = 2.0 * radius * math.sin(math.radians(w2)*self._degreesPerAU)
1982 l, w, w2 = -l, -w, -w2
1983 tr = self._tracer()
1984 dl = self._delay()
1986 self._tracer(0, 0)
1988 self.speed(0)
1989 self._rotate(w2)
1991 self.speed(speed)
1992 self._go(l)
1993 self.speed(0)
1994 self._rotate(w)
1995 self._rotate(-w2)
1997 self._tracer(tr, dl)
1998 self.speed(speed)
1999 if self.undobuffer:
2000 self.undobuffer.cumulate = False
2004 def speed(self, s=0): argument
2005 """dummy method - to be overwritten by child class"""
2006 def _tracer(self, a=None, b=None): argument
2007 """dummy method - to be overwritten by child class"""
2008 def _delay(self, n=None): argument
2009 """dummy method - to be overwritten by child class"""
2026 def __init__(self, resizemode=_CFG["resizemode"]): argument
2027 self._resizemode = resizemode # or "user" or "noresize"
2028 self.undobuffer = None
2029 TPen._reset(self)
2031 def _reset(self, pencolor=_CFG["pencolor"], argument
2033 self._pensize = 1
2034 self._shown = True
2035 self._pencolor = pencolor
2036 self._fillcolor = fillcolor
2037 self._drawing = True
2038 self._speed = 3
2039 self._stretchfactor = (1., 1.)
2040 self._shearfactor = 0.
2041 self._tilt = 0.
2042 self._shapetrafo = (1., 0., 0., 1.)
2043 self._outlinewidth = 1
2045 def resizemode(self, rmode=None): argument
2049 rmode -- one of the strings "auto", "user", "noresize"
2052 - "auto" adapts the appearance of the turtle
2054 - "user" adapts the appearance of the turtle according to the
2057 - "noresize" no adaption of the turtle's appearance takes place.
2058 If no argument is given, return current resizemode.
2068 return self._resizemode
2071 self.pen(resizemode=rmode)
2073 def pensize(self, width=None): argument
2079 width -- positive number
2083 the same line thickness. If no argument is given, current pensize
2092 return self._pensize
2093 self.pen(pensize=width)
2096 def penup(self): argument
2097 """Pull the pen up -- no drawing when moving.
2101 No argument
2106 if not self._drawing:
2108 self.pen(pendown=False)
2110 def pendown(self): argument
2111 """Pull the pen down -- drawing when moving.
2115 No argument.
2120 if self._drawing:
2122 self.pen(pendown=True)
2124 def isdown(self): argument
2127 No argument.
2137 return self._drawing
2139 def speed(self, speed=None): argument
2143 speed -- an integer in the range 0..10 or a speedstring (see below)
2146 If no argument is given: return current speed.
2160 speed = 0 : *no* animation takes place. forward/back makes turtle jump
2168 return self._speed
2175 self.pen(speed=speed)
2177 def color(self, *args): argument
2217 pcolor = self._colorstr(pcolor)
2218 fcolor = self._colorstr(fcolor)
2219 self.pen(pencolor=pcolor, fillcolor=fcolor)
2221 return self._color(self._pencolor), self._color(self._fillcolor)
2223 def pencolor(self, *args): argument
2228 - pencolor()
2230 possibly in hex-number format (see example).
2232 - pencolor(colorstring)
2234 - pencolor((r, g, b))
2238 - pencolor(r, g, b)
2253 color = self._colorstr(args)
2254 if color == self._pencolor:
2256 self.pen(pencolor=color)
2258 return self._color(self._pencolor)
2260 def fillcolor(self, *args): argument
2265 - fillcolor()
2267 possibly in hex-number format (see example).
2269 - fillcolor(colorstring)
2271 - fillcolor((r, g, b))
2275 - fillcolor(r, g, b)
2289 color = self._colorstr(args)
2290 if color == self._fillcolor:
2292 self.pen(fillcolor=color)
2294 return self._color(self._fillcolor)
2296 def showturtle(self): argument
2301 No argument.
2307 self.pen(shown=True)
2309 def hideturtle(self): argument
2314 No argument.
2323 self.pen(shown=False)
2325 def isvisible(self): argument
2328 No argument.
2335 return self._shown
2337 def pen(self, pen=None, **pendict): argument
2341 pen -- a dictionary with some or all of the below listed keys.
2342 **pendict -- one or more keyword-arguments with the below
2345 Return or set the pen's attributes in a 'pen-dictionary'
2349 "pencolor" : color-string or color-tuple
2350 "fillcolor" : color-string or color-tuple
2360 pen()-call to restore the former pen-state. Moreover one
2361 or more of these attributes can be provided as keyword-arguments.
2384 _pd = {"shown" : self._shown,
2385 "pendown" : self._drawing,
2386 "pencolor" : self._pencolor,
2387 "fillcolor" : self._fillcolor,
2388 "pensize" : self._pensize,
2389 "speed" : self._speed,
2390 "resizemode" : self._resizemode,
2391 "stretchfactor" : self._stretchfactor,
2392 "shearfactor" : self._shearfactor,
2393 "outline" : self._outlinewidth,
2394 "tilt" : self._tilt
2404 p.update(pendict)
2410 if self.undobuffer:
2411 self.undobuffer.push(("pen", _p_buf))
2415 if self._drawing != p["pendown"]:
2419 p["pencolor"] = self._colorstr((p["pencolor"],))
2420 if self._pencolor != p["pencolor"]:
2423 if self._pensize != p["pensize"]:
2426 self._newLine()
2428 self._drawing = p["pendown"]
2430 self._pencolor = p["pencolor"]
2432 self._pensize = p["pensize"]
2435 p["fillcolor"] = self._colorstr((p["fillcolor"],))
2436 self._fillcolor = p["fillcolor"]
2438 self._speed = p["speed"]
2440 self._resizemode = p["resizemode"]
2445 self._stretchfactor = sf
2447 self._shearfactor = p["shearfactor"]
2449 self._outlinewidth = p["outline"]
2451 self._shown = p["shown"]
2453 self._tilt = p["tilt"]
2455 scx, scy = self._stretchfactor
2456 shf = self._shearfactor
2457 sa, ca = math.sin(self._tilt), math.cos(self._tilt)
2458 self._shapetrafo = ( scx*ca, scy*(shf*ca + sa),
2459 -scx*sa, scy*(ca - shf*sa))
2460 self._update()
2464 def _newLine(self, usePos = True): argument
2465 """dummy method - to be overwritten by child class"""
2466 def _update(self, count=True, forced=False): argument
2467 """dummy method - to be overwritten by child class"""
2468 def _color(self, args): argument
2469 """dummy method - to be overwritten by child class"""
2470 def _colorstr(self, args): argument
2471 """dummy method - to be overwritten by child class"""
2486 def __init__(self, screen, shapeIndex): argument
2487 self.screen = screen
2488 self._type = None
2489 self._setshape(shapeIndex)
2491 def _setshape(self, shapeIndex): argument
2492 screen = self.screen
2493 self.shapeIndex = shapeIndex
2494 if self._type == "polygon" == screen._shapes[shapeIndex]._type:
2496 if self._type == "image" == screen._shapes[shapeIndex]._type:
2498 if self._type in ["image", "polygon"]:
2499 screen._delete(self._item)
2500 elif self._type == "compound":
2501 for item in self._item:
2503 self._type = screen._shapes[shapeIndex]._type
2504 if self._type == "polygon":
2505 self._item = screen._createpoly()
2506 elif self._type == "image":
2507 self._item = screen._createimage(screen._shapes["blank"]._data)
2508 elif self._type == "compound":
2509 self._item = [screen._createpoly() for item in
2520 def __init__(self, canvas=None, argument
2525 self.screen = canvas
2529 self.screen = canvas
2533 self.screen = screen
2536 self.screen = TurtleScreen(canvas)
2537 RawTurtle.screens.append(self.screen)
2541 screen = self.screen
2542 TNavigator.__init__(self, screen.mode())
2543 TPen.__init__(self)
2544 screen._turtles.append(self)
2545 self.drawingLineItem = screen._createline()
2546 self.turtle = _TurtleImage(screen, shape)
2547 self._poly = None
2548 self._creatingPoly = False
2549 self._fillitem = self._fillpath = None
2550 self._shown = visible
2551 self._hidden_from_screen = False
2552 self.currentLineItem = screen._createline()
2553 self.currentLine = [self._position]
2554 self.items = [self.currentLineItem]
2555 self.stampItems = []
2556 self._undobuffersize = undobuffersize
2557 self.undobuffer = Tbuffer(undobuffersize)
2558 self._update()
2560 def reset(self): argument
2563 No argument.
2565 Delete the turtle's drawings from the screen, re-center the turtle
2570 (0.00,-22.00)
2579 TNavigator.reset(self)
2580 TPen._reset(self)
2581 self._clear()
2582 self._drawturtle()
2583 self._update()
2585 def setundobuffer(self, size): argument
2589 size -- an integer or None
2592 Size gives the maximum number of turtle-actions that can be undone
2594 If size is None, no undobuffer is present.
2600 self.undobuffer = None
2602 self.undobuffer = Tbuffer(size)
2604 def undobufferentries(self): argument
2607 No argument.
2613 if self.undobuffer is None:
2615 return self.undobuffer.nr_of_items()
2617 def _clear(self): argument
2619 self._fillitem = self._fillpath = None
2620 for item in self.items:
2621 self.screen._delete(item)
2622 self.currentLineItem = self.screen._createline()
2623 self.currentLine = []
2624 if self._drawing:
2625 self.currentLine.append(self._position)
2626 self.items = [self.currentLineItem]
2627 self.clearstamps()
2628 self.setundobuffer(self._undobuffersize)
2631 def clear(self): argument
2634 No arguments.
2643 self._clear()
2644 self._update()
2646 def _update_data(self): argument
2647 self.screen._incrementudc()
2648 if self.screen._updatecounter != 0:
2650 if len(self.currentLine)>1:
2651 self.screen._drawline(self.currentLineItem, self.currentLine,
2652 self._pencolor, self._pensize)
2654 def _update(self): argument
2655 """Perform a Turtle-data update.
2657 screen = self.screen
2661 self._update_data()
2662 self._drawturtle()
2666 self._update_data()
2672 def _tracer(self, flag=None, delay=None): argument
2673 """Turns turtle animation on/off and set delay for update drawings.
2676 n -- nonnegative integer
2677 delay -- nonnegative integer
2679 If n is given, only each n-th regular screen update is really performed.
2691 return self.screen.tracer(flag, delay)
2693 def _color(self, args): argument
2694 return self.screen._color(args)
2696 def _colorstr(self, args): argument
2697 return self.screen._colorstr(args)
2699 def _cc(self, args): argument
2708 if self.screen._colormode == 1.0:
2714 def clone(self): argument
2717 No argument.
2726 screen = self.screen
2727 self._newLine(self._drawing)
2729 turtle = self.turtle
2730 self.screen = None
2731 self.turtle = None # too make self deepcopy-able
2733 q = deepcopy(self)
2735 self.screen = screen
2736 self.turtle = turtle
2739 q.turtle = _TurtleImage(screen, self.turtle.shapeIndex)
2742 ttype = screen._shapes[self.turtle.shapeIndex]._type
2749 screen._shapes[self.turtle.shapeIndex]._data]
2754 def shape(self, name=None): argument
2758 name -- a string, which is a valid shapename
2765 To learn about how to deal with shapes see Screen-method register_shape.
2775 return self.turtle.shapeIndex
2776 if not name in self.screen.getshapes():
2777 raise TurtleGraphicsError("There is no shape named %s" % name)
2778 self.turtle._setshape(name)
2779 self._update()
2781 def shapesize(self, stretch_wid=None, stretch_len=None, outline=None): argument
2789 Return or set the pen's attributes x/y-stretchfactors and/or outline.
2803 stretch_wid, stretch_len = self._stretchfactor
2804 return stretch_wid, stretch_len, self._outlinewidth
2813 stretchfactor = self._stretchfactor[0], stretch_len
2815 stretchfactor = self._stretchfactor
2817 outline = self._outlinewidth
2818 self.pen(resizemode="user",
2821 def shearfactor(self, shear=None): argument
2824 Optional argument: shear -- number, tangent of the shear angle
2841 return self._shearfactor
2842 self.pen(resizemode="user", shearfactor=shear)
2844 def settiltangle(self, angle): argument
2847 Argument: angle -- number
2850 regardless of its current tilt-angle. DO NOT change the turtle's
2861 >>> turtle.settiltangle(-45)
2869 self.tiltangle(angle)
2871 def tiltangle(self, angle=None): argument
2872 """Set or return the current tilt-angle.
2874 Optional argument: angle -- number
2877 regardless of its current tilt-angle. DO NOT change the turtle's
2879 If angle is not given: return the current tilt-angle, i. e. the angle
2896 >>> turtle.tiltangle(-45)
2903 tilt = -math.degrees(self._tilt) * self._angleOrient
2904 return (tilt / self._degreesPerAU) % self._fullcircle
2906 tilt = -angle * self._degreesPerAU * self._angleOrient
2908 self.pen(resizemode="user", tilt=tilt)
2910 def tilt(self, angle): argument
2914 angle - a number
2916 Rotate the turtleshape by angle from its current tilt-angle,
2927 self.tiltangle(angle + self.tiltangle())
2929 def shapetransform(self, t11=None, t12=None, t21=None, t22=None): argument
2932 Optional arguments: t11, t12, t21, t22 -- numbers.
2945 >>> turtle.shearfactor(-0.5)
2947 (4.0, -1.0, -0.0, 2.0)
2950 return self._shapetrafo
2951 m11, m12, m21, m22 = self._shapetrafo
2956 if t11 * t22 - t12 * t21 == 0:
2958 self._shapetrafo = (m11, m12, m21, m22)
2959 alfa = math.atan2(-m21, m11) % math.tau
2961 a11, a12, a21, a22 = (ca*m11 - sa*m21, ca*m12 - sa*m22,
2963 self._stretchfactor = a11, a22
2964 self._shearfactor = a12/a22
2965 self._tilt = alfa
2966 self.pen(resizemode="user")
2969 def _polytrafo(self, poly): argument
2973 screen = self.screen
2974 p0, p1 = self._position
2975 e0, e1 = self._orient
2978 return [(p0+(e1*x+e0*y)/screen.xscale, p1+(-e0*x+e1*y)/screen.yscale)
2981 def get_shapepoly(self): argument
2984 No argument.
2988 >>> turtle.shapetransform(4, -1, 0, 2)
2990 ((50, -20), (30, 20), (-50, 20), (-30, -20))
2993 shape = self.screen._shapes[self.turtle.shapeIndex]
2995 return self._getshapepoly(shape._data, shape._type == "compound")
2998 def _getshapepoly(self, polygon, compound=False): argument
3002 if self._resizemode == "user" or compound:
3003 t11, t12, t21, t22 = self._shapetrafo
3004 elif self._resizemode == "auto":
3005 l = max(1, self._pensize/5.0)
3007 elif self._resizemode == "noresize":
3011 def _drawturtle(self): argument
3014 screen = self.screen
3015 shape = screen._shapes[self.turtle.shapeIndex]
3017 titem = self.turtle._item
3018 if self._shown and screen._updatecounter == 0 and screen._tracing > 0:
3019 self._hidden_from_screen = False
3022 if self._resizemode == "noresize": w = 1
3023 elif self._resizemode == "auto": w = self._pensize
3024 else: w =self._outlinewidth
3025 shape = self._polytrafo(self._getshapepoly(tshape))
3026 fc, oc = self._fillcolor, self._pencolor
3030 screen._drawimage(titem, self._position, tshape)
3033 poly = self._polytrafo(self._getshapepoly(poly, True))
3034 screen._drawpoly(item, poly, fill=self._cc(fc),
3035 outline=self._cc(oc), width=self._outlinewidth, top=True)
3037 if self._hidden_from_screen:
3042 screen._drawimage(titem, self._position,
3047 self._hidden_from_screen = True
3051 def stamp(self): argument
3054 No argument.
3066 screen = self.screen
3067 shape = screen._shapes[self.turtle.shapeIndex]
3072 if self._resizemode == "noresize": w = 1
3073 elif self._resizemode == "auto": w = self._pensize
3074 else: w =self._outlinewidth
3075 shape = self._polytrafo(self._getshapepoly(tshape))
3076 fc, oc = self._fillcolor, self._pencolor
3081 screen._drawimage(stitem, self._position, tshape)
3089 poly = self._polytrafo(self._getshapepoly(poly, True))
3090 screen._drawpoly(item, poly, fill=self._cc(fc),
3091 outline=self._cc(oc), width=self._outlinewidth, top=True)
3092 self.stampItems.append(stitem)
3093 self.undobuffer.push(("stamp", stitem))
3096 def _clearstamp(self, stampid): argument
3099 if stampid in self.stampItems:
3102 self.screen._delete(subitem)
3104 self.screen._delete(stampid)
3105 self.stampItems.remove(stampid)
3109 buf = self.undobuffer
3115 buf.ptr = (buf.ptr - 1) % buf.bufsize
3118 def clearstamp(self, stampid): argument
3122 stampid - an integer, must be return value of previous stamp() call.
3130 self._clearstamp(stampid)
3131 self._update()
3133 def clearstamps(self, n=None): argument
3137 n -- an integer
3148 >>> turtle.clearstamps(-2)
3152 toDelete = self.stampItems[:]
3154 toDelete = self.stampItems[:n]
3156 toDelete = self.stampItems[n:]
3158 self._clearstamp(item)
3159 self._update()
3161 def _goto(self, end): argument
3166 ## Version with undo-stuff
3167 go_modes = ( self._drawing,
3168 self._pencolor,
3169 self._pensize,
3170 isinstance(self._fillpath, list))
3171 screen = self.screen
3172 undo_entry = ("go", self._position, end, go_modes,
3173 (self.currentLineItem,
3174 self.currentLine[:],
3175 screen._pointlist(self.currentLineItem),
3176 self.items[:])
3178 if self.undobuffer:
3179 self.undobuffer.push(undo_entry)
3180 start = self._position
3181 if self._speed and screen._tracing == 1:
3182 diff = (end-start)
3184 nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
3191 self._position = start + delta * n
3192 if self._drawing:
3193 screen._drawline(self.drawingLineItem,
3194 (start, self._position),
3195 self._pencolor, self._pensize, top)
3196 self._update()
3197 if self._drawing:
3198 screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
3199 fill="", width=self._pensize)
3201 if self._drawing: # now update currentLine
3202 self.currentLine.append(end)
3203 if isinstance(self._fillpath, list):
3204 self._fillpath.append(end)
3206 self._position = end
3207 if self._creatingPoly:
3208 self._poly.append(end)
3209 if len(self.currentLine) > 42: # 42! answer to the ultimate question
3211 self._newLine()
3212 self._update() #count=True)
3214 def _undogoto(self, entry): argument
3220 screen = self.screen
3221 if abs(self._position - new) > 0.5:
3222 print ("undogoto: HALLO-DA-STIMMT-WAS-NICHT!")
3224 self.currentLineItem = cLI
3225 self.currentLine = cL
3233 todelete = [i for i in self.items if (i not in items) and
3237 self.items.remove(i)
3240 if self._speed and screen._tracing == 1:
3241 diff = old - new
3243 nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
3250 self._position = new + delta * n
3252 screen._drawline(self.drawingLineItem,
3253 (start, self._position),
3255 self._update()
3257 screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
3260 self._position = old
3265 if self._creatingPoly:
3266 if len(self._poly) > 0:
3267 self._poly.pop()
3268 if self._poly == []:
3269 self._creatingPoly = False
3270 self._poly = None
3272 if self._fillpath == []:
3273 self._fillpath = None
3275 elif self._fillpath is not None:
3276 self._fillpath.pop()
3277 self._update() #count=True)
3279 def _rotate(self, angle): argument
3282 if self.undobuffer:
3283 self.undobuffer.push(("rot", angle, self._degreesPerAU))
3284 angle *= self._degreesPerAU
3285 neworient = self._orient.rotate(angle)
3286 tracing = self.screen._tracing
3287 if tracing == 1 and self._speed > 0:
3288 anglevel = 3.0 * self._speed
3292 self._orient = self._orient.rotate(delta)
3293 self._update()
3294 self._orient = neworient
3295 self._update()
3297 def _newLine(self, usePos=True): argument
3302 if len(self.currentLine) > 1:
3303 self.screen._drawline(self.currentLineItem, self.currentLine,
3304 self._pencolor, self._pensize)
3305 self.currentLineItem = self.screen._createline()
3306 self.items.append(self.currentLineItem)
3308 self.screen._drawline(self.currentLineItem, top=True)
3309 self.currentLine = []
3311 self.currentLine = [self._position]
3313 def filling(self): argument
3316 No argument.
3325 return isinstance(self._fillpath, list)
3327 def begin_fill(self): argument
3330 No argument.
3338 if not self.filling():
3339 self._fillitem = self.screen._createpoly()
3340 self.items.append(self._fillitem)
3341 self._fillpath = [self._position]
3342 self._newLine()
3343 if self.undobuffer:
3344 self.undobuffer.push(("beginfill", self._fillitem))
3345 self._update()
3348 def end_fill(self): argument
3351 No argument.
3359 if self.filling():
3360 if len(self._fillpath) > 2:
3361 self.screen._drawpoly(self._fillitem, self._fillpath,
3362 fill=self._fillcolor)
3363 if self.undobuffer:
3364 self.undobuffer.push(("dofill", self._fillitem))
3365 self._fillitem = self._fillpath = None
3366 self._update()
3368 def dot(self, size=None, *color): argument
3372 size -- an integer >= 1 (if given)
3373 color -- a colorstring or a numeric color tuple
3384 color = self._colorstr(size)
3385 size = self._pensize + max(self._pensize, 4)
3387 color = self._pencolor
3389 size = self._pensize + max(self._pensize, 4)
3392 size = self._pensize + max(self._pensize, 4)
3393 color = self._colorstr(color)
3394 if hasattr(self.screen, "_dot"):
3395 item = self.screen._dot(self._position, size, color)
3396 self.items.append(item)
3397 if self.undobuffer:
3398 self.undobuffer.push(("dot", item))
3400 pen = self.pen()
3401 if self.undobuffer:
3402 self.undobuffer.push(["seq"])
3403 self.undobuffer.cumulate = True
3405 if self.resizemode() == 'auto':
3406 self.ht()
3407 self.pendown()
3408 self.pensize(size)
3409 self.pencolor(color)
3410 self.forward(0)
3412 self.pen(pen)
3413 if self.undobuffer:
3414 self.undobuffer.cumulate = False
3416 def _write(self, txt, align, font): argument
3419 item, end = self.screen._write(self._position, txt, align, font,
3420 self._pencolor)
3421 self._update()
3422 self.items.append(item)
3423 if self.undobuffer:
3424 self.undobuffer.push(("wri", item))
3427 def write(self, arg, move=False, align="left", font=("Arial", 8, "normal")): argument
3431 arg -- info, which is to be written to the TurtleScreen
3432 move (optional) -- True/False
3433 align (optional) -- one of the strings "left", "center" or right"
3434 font (optional) -- a triple (fontname, fontsize, fonttype)
3436 Write text - the string representation of arg - at the current
3439 If move is True, the pen is moved to the bottom-right corner
3446 if self.undobuffer:
3447 self.undobuffer.push(["seq"])
3448 self.undobuffer.cumulate = True
3449 end = self._write(str(arg), align.lower(), font)
3451 x, y = self.pos()
3452 self.setpos(end, y)
3453 if self.undobuffer:
3454 self.undobuffer.cumulate = False
3456 def begin_poly(self): argument
3459 No argument.
3467 self._poly = [self._position]
3468 self._creatingPoly = True
3470 def end_poly(self): argument
3473 No argument.
3481 self._creatingPoly = False
3483 def get_poly(self): argument
3486 No argument.
3493 if self._poly is not None:
3494 return tuple(self._poly)
3496 def getscreen(self): argument
3499 No argument.
3502 So TurtleScreen-methods can be called for that object.
3510 return self.screen
3512 def getturtle(self): argument
3515 No argument.
3527 return self
3536 def _delay(self, delay=None): argument
3539 return self.screen.delay(delay)
3541 def onclick(self, fun, btn=1, add=None): argument
3542 """Bind fun to mouse-click event on this turtle on canvas.
3545 fun -- a function with two arguments, to which will be assigned
3547 btn -- number of the mouse-button defaults to 1 (left mouse button).
3548 add -- True or False. If True, new binding will be added, otherwise
3557 >>> onclick(None) # event-binding will be removed
3559 self.screen._onclick(self.turtle._item, fun, btn, add)
3560 self._update()
3562 def onrelease(self, fun, btn=1, add=None): argument
3563 """Bind fun to mouse-button-release event on this turtle on canvas.
3566 fun -- a function with two arguments, to which will be assigned
3568 btn -- number of the mouse-button defaults to 1 (left mouse button).
3572 ... def glow(self,x,y):
3573 ... self.fillcolor("red")
3574 ... def unglow(self,x,y):
3575 ... self.fillcolor("")
3584 self.screen._onrelease(self.turtle._item, fun, btn, add)
3585 self._update()
3587 def ondrag(self, fun, btn=1, add=None): argument
3588 """Bind fun to mouse-move event on this turtle on canvas.
3591 fun -- a function with two arguments, to which will be assigned
3593 btn -- number of the mouse-button defaults to 1 (left mouse button).
3595 Every sequence of mouse-move-events on a turtle is preceded by a
3596 mouse-click event on that turtle.
3605 self.screen._ondrag(self.turtle._item, fun, btn, add)
3608 def _undo(self, action, data): argument
3611 if self.undobuffer is None:
3615 self._rotate(-angle*degPAU/self._degreesPerAU)
3616 dummy = self.undobuffer.pop()
3619 self.clearstamp(stitem)
3621 self._undogoto(data)
3624 self.screen._delete(item)
3625 self.items.remove(item)
3628 self.screen._drawpoly(item, ((0, 0),(0, 0),(0, 0)),
3632 self._fillitem = self._fillpath = None
3633 if item in self.items:
3634 self.screen._delete(item)
3635 self.items.remove(item)
3637 TPen.pen(self, data[0])
3638 self.undobuffer.pop()
3640 def undo(self): argument
3643 No argument.
3657 if self.undobuffer is None:
3659 item = self.undobuffer.pop()
3665 self._undo(item[0], item[1:])
3667 self._undo(action, data)
3673 ### Screen - Singleton ########################
3689 def __init__(self): argument
3690 # XXX there is no need for this code to be conditional,
3696 _Screen._root = self._root = _Root()
3697 self._root.title(_Screen._title)
3698 self._root.ondestroy(self._destroy)
3706 self._root.setupcanvas(width, height, canvwidth, canvheight)
3707 _Screen._canvas = self._root._getcanvas()
3708 TurtleScreen.__init__(self, _Screen._canvas)
3709 self.setup(width, height, leftright, topbottom)
3711 def setup(self, width=_CFG["width"], height=_CFG["height"], argument
3736 if not hasattr(self._root, "set_geometry"):
3738 sw = self._root.win_width()
3739 sh = self._root.win_height()
3743 startx = (sw - width) / 2
3747 starty = (sh - height) / 2
3748 self._root.set_geometry(width, height, startx, starty)
3749 self.update()
3751 def title(self, titlestring): argument
3752 """Set title of turtle-window
3755 titlestring -- a string, to appear in the titlebar of the
3758 This is a method of Screen-class. Not available for TurtleScreen-
3762 >>> screen.title("Welcome to the turtle-zoo!")
3768 def _destroy(self): argument
3769 root = self._root
3778 def bye(self): argument
3784 self._destroy()
3786 def exitonclick(self): argument
3789 No arguments.
3792 If "using_IDLE" - value in configuration dictionary is False
3794 If IDLE with -n switch (no subprocess) is used, this value should be
3798 This is a method of the Screen-class and not available for
3806 """Screen.bye() with two dummy-parameters"""
3807 self.bye()
3808 self.onclick(exitGracefully)
3817 """RawTurtle auto-creating (scrolled) canvas.
3825 def __init__(self, argument
3831 RawTurtle.__init__(self, Turtle._screen,
3839 """Create and write docstring-dictionary to file.
3842 filename -- a string, used as filename
3845 Has to be called explicitly, (not used by the turtle-graphics classes)
3863 for key in keys[:-1]:
3866 key = keys[-1]
3873 """Read in docstrings from lang-specific docstring dictionary.
3875 Transfer docstrings, translated to lang, from a dictionary-file
3876 to the methods of classes Screen and Turtle and - in revised form -
3887 print("Bad docstring-entry: %s" % key)
3897 print ("Unknown Error when trying to import %s-docstring-dictionary" %
3907 call. The "self" parameter is not included.
3910 # bit of a hack for methods - turn it into a function
3911 # but we drop the "self" param.
3918 defaults = [""] * (len(realArgs)-len(defaults)) + defaults
4004 """Demo of old turtle.py - module"""
4077 for i in range(-2, 16):
4080 fillcolor(255-15*i, 0, 15*i)