2

I have a 2 vertical lines on a canvas with a gap in the middle (generated randomly every time). This line starts on the right side of the canvas. When I click the "l" key it runs a function that moves the line left by 5, and you can keep clicking "l" until it reaches the left side. I want to know how to set it up so I only have to press the "l" key once and the line will slowly move across the screen until it reaches the left side. Any help would be appreciated

import random
import time
from tkinter import *


window = Tk()
window.geometry("300x300")
window.title("GUI")
window.resizable(FALSE, FALSE)

label1 = Label(window, text="My First GUI", font=("arial", 16, "bold"))
label1.pack()
canvas = Canvas()
canvas.config(bg="gray")
canvas.place(width=300, height=150, x=0, y=150)


def key_pressed(event):
    if event.char == "l":
        move_line()


def create_gap():
    gap_ycoords = []
    # random number between 10 and 95 in increments of 5
    first_line_end = random.randrange(10, 96, 5)
    gap_ycoords.append(first_line_end)
    second_line_start = first_line_end + 50
    gap_ycoords.append(second_line_start)
    return gap_ycoords


def draw_line_obstacle(canvas_ref):
    y_coord = create_gap()
    top_line = canvas_ref.create_line(295, 5, 295, y_coord[0], tags="top_line")
    bottom_line = canvas_ref.create_line(295, y_coord[1], 295, 145, tags="bottom_line")


draw_line_obstacle(canvas)


def move_line():
    if canvas.coords("top_line")[0] > 5:
        tcoords = canvas.coords("top_line")
        bcoords = canvas.coords("bottom_line")
        canvas.coords("top_line", tcoords[0] - 5, tcoords[1], tcoords[2] - 5, tcoords[3])
        canvas.coords("bottom_line", bcoords[0] - 5, bcoords[1], bcoords[2] - 5, bcoords[3])


window.bind("<Key>", key_pressed)

window.mainloop()
Tedious
  • 75
  • 6
  • This question already has answers here:[tkinter: how to use after method](https://stackoverflow.com/a/25753719/7414759) – stovfl Jun 23 '20 at 21:12
  • First use `after()` to move the lines periodically until the lines reach the left end position. Second you need to ignore the key if the lines are still moving. – acw1668 Jun 24 '20 at 00:31

2 Answers2

1

You're so close! Only one more line needed in your move_line function:

def move_line():
    if canvas.coords("top_line")[0] > 5:
        ... # other code
        canvas.after(100, move_line) # delay in ms, lower=faster movement
Tresdon
  • 1,211
  • 8
  • 18
0

You need to use .after(). This basically calls a function every, say, 20 milliseconds.

Calling this function repeatedly will make it so that when you press the "l" key once, the line will move to the other end of the screen.

Code:

import random
import time
from tkinter import *


window = Tk()
window.geometry("300x300")
window.title("GUI")
window.resizable(FALSE, FALSE)

label1 = Label(window, text="My First GUI", font=("arial", 16, "bold"))
label1.pack()
canvas = Canvas()
canvas.config(bg="gray")
canvas.place(width=300, height=150, x=0, y=150)


def key_pressed(event = None):
    move_line()
    window.after(20, key_pressed)




def create_gap():
    gap_ycoords = []
    # random number between 10 and 95 in increments of 5
    first_line_end = random.randrange(10, 96, 5)
    gap_ycoords.append(first_line_end)
    second_line_start = first_line_end + 50
    gap_ycoords.append(second_line_start)
    return gap_ycoords


def draw_line_obstacle(canvas_ref):
    y_coord = create_gap()
    top_line = canvas_ref.create_line(295, 5, 295, y_coord[0], tags="top_line")
    bottom_line = canvas_ref.create_line(295, y_coord[1], 295, 145, tags="bottom_line")


draw_line_obstacle(canvas)


def move_line():
    if canvas.coords("top_line")[0] > 5:
        tcoords = canvas.coords("top_line")
        bcoords = canvas.coords("bottom_line")
        canvas.coords("top_line", tcoords[0] - 5, tcoords[1], tcoords[2] - 5, tcoords[3])
        canvas.coords("bottom_line", bcoords[0] - 5, bcoords[1], bcoords[2] - 5, bcoords[3])


window.bind("<l>", key_pressed)

window.mainloop()

On this line: window.after(20, key_pressed), you can change the number 20 to something higher to move slower, and something lower to move faster.

Hope this helps!

10 Rep
  • 2,217
  • 7
  • 19
  • 33