Кнопка «Стоп» в Ткинтере - PullRequest
0 голосов
/ 15 ноября 2018

Я пытаюсь запустить анимацию черепахи с помощью кнопки и остановиться с помощью кнопки.Начать с кнопки очень легко, но я не могу понять, что такое кнопка остановки?Вот мой код:

import turtle
import tkinter as tk
def start():
    t.forward(100)
    t.right(90)
    t.forward(100)
    t.left(90)
    t.forward(100)
    t.right(90)
    t.forward(100)
    t.right(90)
    t.forward(100)

def stop():
    t.stop

def clear():
    canvas.delete("all")

root = tk.Tk()
canvas = tk.Canvas(width = 500, height = 500)
canvas.pack()

t = turtle.RawTurtle(canvas)

tk.Button(text = "Start", command = start).pack(side = tk.LEFT)
tk.Button(text = "Stop", command = stop).pack(side = tk.LEFT)
tk.Button(text = "Clear", command = clear).pack(side = tk.LEFT)

root.mainloop()

Также кнопка очистки работает, но после этого кнопка запуска больше не работает.Если кто-то может помочь мне и в этом.

Спасибо @Mike - SMT за помощь мне с этим кодом.Вот отредактированный и полностью работающий код:

import turtle
import tkinter as tk


def start(turtle_object, draw_path):
    global tracker, start_ndex, end_ndex, started
    tracker = False
    if started == False:
        started = True
        for i in range(start_ndex, end_ndex):
            if tracker == False and i <= end_ndex:
                pth = draw_path[i]
                if pth[0] == "f":
                    turtle_object.forward(pth[1])
                elif pth[0] == "r":
                    turtle_object.right(pth[1])
                elif pth[0] == "l":
                    turtle_object.left(pth[1])
                start_ndex += 1


running = True

def stop():
    global tracker, started
    tracker = True
    started = False

def clear():
    global t, tracker, started, start_ndex
    t.reset()
    start_ndex = 0
    started = False
    t = turtle.RawTurtle(canvas)


root = tk.Tk()
tracker = False
start_ndex = 0
started = False # added this tracking variable to prevent issues with     spamming the start button.

draw_path = [["f", 100], ["r", 90], ["f", 100], ["l", 90], ["f", 100], ["r", 90], ["f", 100], ["r", 90], ["f", 100]]


end_ndex = len(draw_path)

canvas = tk.Canvas(width = 500, height = 500)
canvas.pack()

t = turtle.RawTurtle(canvas)
tk.Button(text = "Start", command = lambda: start(t, draw_path)).pack(side = tk.LEFT)
tk.Button(text = "Stop", command = stop).pack(side = tk.LEFT)
tk.Button(text = "Clear", command = clear).pack(side = tk.LEFT)
root.mainloop()

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Я согласен с идеями в ответе @ Mike-SMT, но я бы пошел по-другому. Мне кажется, что черепаха и ее элементы управления очень похожи на генератор Python, поэтому я переписал ее как таковую. Черепаха движется по пути, по одному пикселю за раз, давая контроль, который может возвращаться или не возвращаться. Или он может исчерпать свой путь и остановить итерацию:

import tkinter as tk
from turtle import RawTurtle

PATH = [(100.00, 0.00), (100.00, -100.00), (200.00, -100.00), (200.00, -200.00), (100.00, -200.00)]

def run():
    for position in PATH:
        turtle.setheading(turtle.towards(position))

        while turtle.distance(position) > 1:
            turtle.forward(1)
            yield

def start():
    global generator, running

    running = True

    while running:
        try:
            next(generator)

        except ValueError:  # user clicked start but already running
            return

        except TypeError:  # new run
            turtle.reset()
            generator = run()

        except StopIteration:  # end of complete run
            generator = None
            running = False
            break

def stop():
    global running
    running = False

def clear():
    global generator
    turtle.reset()
    generator = None

root = tk.Tk()
canvas = tk.Canvas(width=500, height=500)
canvas.pack()

turtle = RawTurtle(canvas, "turtle")

running = True
generator = None

tk.Button(text="Start", command=start).pack(side=tk.LEFT, expand=tk.TRUE)
tk.Button(text="Stop", command=stop).pack(side=tk.LEFT, expand=tk.TRUE)
tk.Button(text="Clear", command=clear).pack(side=tk.LEFT, expand=tk.TRUE)

root.mainloop()

Также кнопка очистки работает, но после этого кнопка запуска не работает работать больше. Если кто-то может помочь мне и с этим.

Вы можете заменить текущую clear() функцию на:

def clear():
    t.clear()

если вы просто хотите стереть начертанный путь, но оставьте черепаху там, где она оказалась. Если вы хотите стереть путь и вернуть черепаху обратно в исходную точку, вместо этого выполните:

def clear():
    t.reset()
0 голосов
/ 15 ноября 2018

Вы не можете остановить каждый оператор рисования, если вы не поставите флажок между каждой нарисованной линией.

Приведенный ниже код представляет собой грубый макет того, как вы могли бы сделать что-то, чтобы проверить переменную отслеживания, используемую, чтобы сказать ей больше не рисовать новые линии.

Самое близкое, что вы можете сделать, чтобы прекратить рисовать, это что-то вроде этого:

import turtle
import tkinter as tk

def start():
    global tracker
    tracker = False
    if tracker == False:
        t.forward(100)
    if tracker == False:
        t.right(90)
    if tracker == False:
        t.forward(100)
    if tracker == False:
        t.left(90)
    if tracker == False:
        t.forward(100)
    if tracker == False:
        t.right(90)
    if tracker == False:
        t.forward(100)
    if tracker == False:
        t.right(90)
    if tracker == False:
        t.forward(100)


def stop():
    global tracker
    tracker = True

def clear():
    canvas.delete("all")

root = tk.Tk()
tracker = False
canvas = tk.Canvas(width = 500, height = 500)
canvas.pack()

t = turtle.RawTurtle(canvas)

tk.Button(text = "Start", command = start).pack(side = tk.LEFT)
tk.Button(text = "Stop", command = stop).pack(side = tk.LEFT)
tk.Button(text = "Clear", command = clear).pack(side = tk.LEFT)

root.mainloop()

Это по крайней мере остановит рисование после каждой линии, но вы не можете остановить рисование в средней линии.

Просто для удовольствия, если мы добавим некоторые отслеживающие переменные и используем более чистую логику, мы можем запускать, останавливать и запускать снова.

Обновление: из комментария @ cdlane ниже я добавил отслеживание добавления и обновил функцию очистки. Это должно позволять запуск, запуск, запуск без проблем, а также возможность очистки поля.

import turtle
import tkinter as tk

def start(turtle_object, draw_path):
    global tracker, start_ndex, end_ndex, started
    tracker = False
    if started == False:
        started = True
        for i in range(start_ndex, end_ndex):
            if tracker == False and i <= end_ndex:
                pth = draw_path[i]
                if pth[0] == "f":
                    turtle_object.forward(pth[1])
                elif pth[0] == "r":
                    turtle_object.right(pth[1])
                elif pth[0] == "l":
                    turtle_object.left(pth[1])
                start_ndex += 1

def stop():
    global tracker, started
    tracker = True
    started = False

def clear():
    global t, tracker, started, start_ndex
    canvas.delete("all")
    tracker = False
    start_ndex = 0
    started = False
    t = turtle.RawTurtle(canvas)

root = tk.Tk()
tracker = False
start_ndex = 0
started = False # added this tracking variable to prevent issues with spamming the start button.

draw_path = [["f", 100], ["r", 90], ["f", 100], ["l", 90], ["f", 100], ["r", 90], ["f", 100], ["r", 90], ["f", 100]]


end_ndex = len(draw_path)

canvas = tk.Canvas(width = 500, height = 500)
canvas.pack()

t = turtle.RawTurtle(canvas)
tk.Button(text = "Start", command = lambda: start(t, draw_path)).pack(side = tk.LEFT)
tk.Button(text = "Stop", command = stop).pack(side = tk.LEFT)
tk.Button(text = "Clear", command = clear).pack(side = tk.LEFT)
root.mainloop()
...