Python, how do you stop the menu clicking cycle?



  • Hello, everyone! In the laboratory unit, the challenge was:

    In the shape area, a model of random numbers between 0 and 99 is shown. 6x6. The seamstress was originally located in the left upper corner, and after launch cycling on the perimeter of the time-discretted time-wise matrix 0.8 seconds. After the full cycle, the frame moves against the clockwise, and Then again by clock. Starting motion is a double cheek of the left mice. The shape, the stop is the command of the main menu, which leads to the setting of a framework reference position.

    I think there's a pattern of fingerprints here, and I meant it.

    I can't figure out how to stop the menu cheek cycle. I've got the principle of doing the job in my code: the double-click on the canvas causes a start function that causes a move_clockwise. The one with the full cycle is moving_counterclockwise. And eventually they call each other in line. There's still a question about stopping. Can anyone tell us how to get it?

    from tkinter import *
    import random
    import time
    #from PIL import ImageTk, Image
    root = Tk()
    root.title("Лабораторная работа №4")
    root.geometry('360x360')
    

    width=360
    height=360
    sleep=0.01
    step=15
    work=True

    c = Canvas(root, width=width, height=height, bg="white")
    c.place(x = 0, y = 0)
    oval = c.create_oval(0, 0, 30, 30, fill='green')

    def move_clockwise():
    for i in range((width - 30) // step):
    c.move(oval, step, 0)
    root.update()
    time.sleep(sleep)

    for i in range((height - 30) // step):
        c.move(oval, 0, step)
        root.update()
        time.sleep(sleep)
    
    for i in range((width - 30) // step):
        c.move(oval, -step, 0)
        root.update()
        time.sleep(sleep)
    
    for i in range((height - 30) // step):
        c.move(oval, 0, -step)
        root.update()
        time.sleep(sleep)
    move_counterclockwise()
    

    def move_counterclockwise():
    for i in range((height - 30) // step):
    c.move(oval, 0, step)
    root.update()
    time.sleep(sleep)
    for i in range((width - 30) // step):
    c.move(oval, step, 0)
    root.update()
    time.sleep(sleep)
    for i in range((height - 30) // step):
    c.move(oval, 0, -step)
    root.update()
    time.sleep(sleep)
    for i in range((width - 30) // step):
    c.move(oval, -step, 0)
    root.update()
    time.sleep(sleep)
    move_clockwise()

    def start(event):
    global work
    while work:
    move_clockwise()

    def stop():
    global work
    if work:
    work==False

    #Заполнение матрицы
    for x in range(6):
    for y in range(6):
    text=c.create_text(30+60x, 30+60y, text=str(random.randint(0,99)))

    c.bind('<Double-Button-1>', start)

    menu=Menu(root)
    root.config(menu=menu)
    menu.add_command(label="Stop", command=stop)

    root.mainloop()

    P.S. Please, if PLO does not propose, the teacher does not support it. ♪ ♪



  • One seal and one fundamental error.

    Printing:

        if work:
            work==False   # должно быть просто =
    

    And the mistake is you're calling again. move_clockwise() at the end of the function def move_counterclockwise()♪ As a result, the functions go back to the field and never return to the stop test cycle:

        while work:
            move_clockwise()
    

    Yeah. work = True I'd like to add to the beginning. def start(event):♪ To be able to relaunch the movement.


    Well, the code can be shortened. And stop instantly.

    from tkinter import *
    import random
    import time
    #from PIL import ImageTk, Image
    root = Tk()
    root.title("Лабораторная работа №4")
    root.geometry('360x360')
    

    width=360
    height=360
    sleep=0.02
    step=15
    work=False

    c = Canvas(root, width=width, height=height, bg="white")
    c.place(x = 0, y = 0)
    oval = c.create_oval(0, 0, 30, 30, fill='green')

    def move(figure):
    while True:
    for vertical, increment in ((False, +1), (True , +1), (False, -1), (True , -1), # по часовой
    (True , +1), (False, +1), (True , -1), (False, -1)): # против часовой
    for i in range(((height if vertical else width) - 30) // step):
    if not work:
    c.coords(figure, 0, 0, 30, 30)
    return
    c.move(figure, (0 if vertical else 1) * step * increment, (1 if vertical else 0) * step * increment)
    root.update()
    time.sleep(sleep)

    def start(event):
    global work
    if not work:
    work = True
    move(oval)

    def stop():
    global work
    work = False

    #Заполнение матрицы
    for x in range(6):
    for y in range(6):
    text=c.create_text(30+60x, 30+60y, text=str(random.randint(0,99)))

    c.bind('<Double-Button-1>', start)

    menu=Menu(root)
    root.config(menu=menu)
    menu.add_command(label="Stop", command=stop)

    root.mainloop()


    Besides, the mission is pretty unwise. Given that the movement was to take place with a disrete of 0.8 seconds (and it was a pretty big pause), it might have been because the rudder had to jump on the elements of the matrix. And then, time.sleep() You can't even use it, because he's gonna fries the interface for this time. We need to use the function. after() for the delayed launch of the next displacement. For example, using a generator, the code may look like:

    from tkinter import *
    import random
    import time
    #from PIL import ImageTk, Image
    root = Tk()
    root.title("Лабораторная работа №4")

    sleep = 0.8
    step = 60
    oval_size = 40
    matrix_size = {"W":6, "H":6} # width, height
    offset = (step - oval_size) // 2
    work = False

    root.geometry(f'{matrix_size["W"] * step}x{matrix_size["H"] * step}')
    c = Canvas(root, width=matrix_size["W"] * step, height=matrix_size["H"] * step, bg="white")
    c.place(x = 0, y = 0)
    oval = c.create_oval(offset, offset, offset + oval_size, offset + oval_size)

    def move(gen=None):
    if work:
    next(gen)
    root.after(int(sleep*1000), lambda: move(gen))

    def move_generator():
    while True:
    for vertical, increment in ((False, +1), (True , +1), (False, -1), (True , -1), # по часовой
    (True , +1), (False, +1), (True , -1), (False, -1)): # против часовой
    for i in range(matrix_size["H" if vertical else "W"] - 1):
    c.move(oval, (0 if vertical else 1) * step * increment, (1 if vertical else 0) * step * increment)
    yield

    def start(event):
    global work
    if not work:
    work = True
    move(move_generator())

    def stop():
    global work
    work = False
    c.coords(oval, offset, offset, offset + oval_size, offset + oval_size)

    #Заполнение матрицы
    for x in range(6):
    for y in range(6):
    text=c.create_text(30+60x, 30+60y, text=str(random.randint(0,99)))

    c.bind('<Double-Button-1>', start)

    menu=Menu(root)
    root.config(menu=menu)
    menu.add_command(label="Stop", command=stop)

    root.mainloop()


    It's not a generator.

    from tkinter import *
    import random
    import time

    root = Tk()
    root.title("Лабораторная работа №4")

    sleep = 0.8
    step = 60
    oval_size = 40
    matrix_size = {"W":6, "H":6} # width, height
    offset = (step - oval_size) // 2
    work = False

    root.geometry(f'{matrix_size["W"] * step}x{matrix_size["H"] * step}')
    c = Canvas(root, width=matrix_size["W"] * step, height=matrix_size["H"] * step, bg="white")
    c.place(x = 0, y = 0)
    oval = c.create_oval(offset, offset, offset + oval_size, offset + oval_size)

    movements = []
    for vertical, increment in ((False, +1), (True , +1), (False, -1), (True , -1), # по часовой
    (True , +1), (False, +1), (True , -1), (False, -1)): # против часовой
    for i in range(matrix_size["H" if vertical else "W"] - 1):
    movements.append(((0 if vertical else 1) * step * increment, (1 if vertical else 0) * step * increment))

    def move(pos=0):
    if work:
    c.move(oval, movements[pos])
    root.after(int(sleep
    1000), lambda: move( (pos+1) % len(movements) ))

    def start(event):
    global work
    if not work:
    work = True
    move()

    def stop():
    global work
    work = False
    c.coords(oval, offset, offset, offset + oval_size, offset + oval_size)

    #Заполнение матрицы
    for x in range(6):
    for y in range(6):
    text=c.create_text(30+60x, 30+60y, text=str(random.randint(0,99)))

    c.bind('<Double-Button-1>', start)

    menu=Menu(root)
    root.config(menu=menu)
    menu.add_command(label="Stop", command=stop)

    root.mainloop()



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2