3

Can I change the scrollregion on a Python turtle canvas? I want the drawing to move with it, not just the coordinates to shift. The appearance I'm going for is side-scroller like, where the screen's display region moves to center the turtle onscreen.

I've tried using turtle.setworldcoordinates(llx, lly, urx, ury), but, from the documentation, "This performs a screen.reset()". I've also looked at this SO question , but this involves scroll bars, will not center the turtle easily, and has a limited canvas space. What I'm looking for is something that:

  • Moves the display region to center the turtle
  • Also moves the drawing
  • Has an infinite scroll region
  • does not display scroll bars
  • can be called quickly with a function My best guess would be to be able to have an infinite scrolled canvas somehow, then hide the scroll bars and set them according to turtle position.

Is this possible in Python 2.7? I don't mind if it uses tkinter as well.

EDIT: 6-3-15

I found the canvas.xview and canvas.yview functions, but they don't seem to work once I define screen = turtle.TurtleScreen(canvas), and TurtleScreen has no xview or yview functions. I can't seem to make this work.

Then I found turtle.ScrolledCanvas(). This seems ideal except it has no methods for setting scroll manually from the program. Can I set the scroll manually on a turtle.ScrolledCanvas()???

Community
  • 1
  • 1
Luke Taylor
  • 8,631
  • 8
  • 54
  • 92

1 Answers1

2

The position of a canvas can be changed without a reset using canvas.place() method. It will move the turtle and the drawings too, so the turtle needs to be relocated after every move.

The next code moves the canvas with Left and Right arrows and draws a circle with Space, while keeping the turtle in the center. No ScrolledCanvas needed, just a very large standard canvas:

import turtle
import Tkinter as tk


def keypress(event):
    global xx, canvas, t, speed
    ev = event.keysym
    if ev == 'Left':
        xx += speed
    else:
        xx -= speed

    canvas.place(x=xx)
    t.setposition((-canvas.winfo_width() / 4) - (xx + 250), 0)
    return None


def drawCircle(_):
    global t
    t.pendown()
    t.fillcolor(0, 0, 1.0)
    t.fill(True)
    t.circle(100)
    t.fill(False)
    t.fillcolor(0, 1, 0)
    t.penup()

# Set the main window
window = tk.Tk()
window.geometry('500x500')
window.resizable(False, False)

# Create the canvas. Width is larger than window
canvas = turtle.Canvas(window, width=2000, height=500)
xx = -500
canvas.place(x=xx, y=0)

# Bring the turtle
t = turtle.RawTurtle(canvas)
t.shape('turtle')  # nicer look
t.speed(0)
t.penup()
t.setposition((-canvas.winfo_width() / 4) - (xx + 250), 0)

# key binding
window.bind('<KeyPress-Left>', keypress)
window.bind('<KeyPress-Right>', keypress)
window.bind('<KeyPress-space>', drawCircle)

drawCircle(None)
speed = 3  # scrolling speed
window.mainloop()

Having a real infinite scrolling would require to redraw every item in the canvas every time with the required offset, instead of actually moving or scrolling the canvas. Functions like create_image() can give the illusion of movement with static backgrounds, but it resets the drawings.

bio_c
  • 321
  • 1
  • 8