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=Truec = 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 functiondef 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=Falsec = 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 = Falseroot.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)
yielddef 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 timeroot = 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 = Falseroot.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(sleep1000), 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()