Почему метод «root .after ()» не остановить? - PullRequest
0 голосов
/ 15 февраля 2020

Я пытаюсь сделать простую инструментальную программу с кнопками направления. Это работает, но иногда отпускание кнопки неэффективно, и черепаха перестает просто нажимать кнопку «Домой». Иначе он просто работает непрерывно, как будто я не отпускаю кнопку.

Вот код:

from tkinter import *
from turtle import RawTurtle, TurtleScreen

def showPos():
    monitor.delete('1.0', END)
    monitor.insert(END, "X: " + str(tool.ycor()) +" Z: " + str(tool.xcor()))

def goHome():
    tool.home()
    showPos()
    stop_move()

def goUp():
    tool.sety(tool.ycor() + 10)

def goDown():
    tool.sety(tool.ycor() - 10)

def goRight():
    tool.setx(tool.xcor() + 10)

def goLeft():
    tool.setx(tool.xcor() - 10)

def stop_move():
    global jobid
    root.after_cancel(jobid)

def move(direction):
    global jobid

    if direction == "-X":
        goDown()

    if direction == "+X":
        goUp()    

    if direction == "-Z":
        goLeft()

    if direction == "+Z":
        goRight()    

    jobid = root.after(10, move, direction)
    showPos()

jobid = None

root = Tk()
root.title("CNC Lathe")

canvas = Canvas(root, width=800, height=600)
canvas.pack()

screen = TurtleScreen(canvas)
screen.bgcolor("black")
screen.register_shape("wnmg.gif")

tool = RawTurtle(screen, shape="wnmg.gif")
tool.pencolor("white")

monitor = Text(root, height=1, width=16, font="Helvetica")
monitor.pack()

topFrame = Frame(root)
topFrame.pack()
middleFrame = Frame(root)
middleFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack()

for direction in ("-X", "+X", "-Z", "+Z"):
    if direction == "+X":
        button = Button(topFrame, text=direction)
        button.pack()

    if direction == "-X":
        button = Button(bottomFrame, text=direction)
        button.pack()

    if direction == "-Z":
        button = Button(middleFrame, text=direction)
        button.pack(side=LEFT)

    if direction == "+Z":
        button = Button(middleFrame, text=direction)
        button.pack(side=RIGHT)   

    button.bind('<ButtonPress-1>', lambda event, direction=direction: move(direction))
    button.bind('<ButtonRelease-1>', lambda event: stop_move())

Button(middleFrame, text="Home", command=goHome).pack()

root.mainloop()

Я попытался установить переменную "jobid" в "None" после " root .after_cancel () ", но ничего не изменилось. Время от времени это, кажется, не обнаруживает отпускание кнопки. Кто-нибудь знает решение?

1 Ответ

0 голосов
/ 16 февраля 2020

Я пытался заставить ваш код работать с вашей jobid моделью, и, хотя я мог бы его улучшить, в конце концов обнаружился недостаток - я не могу точно сказать, почему. Вы должны учитывать, что в вашей реализации jobid не всегда представляет ожидающую работу, это может быть та, которая успешно сработала.

Другая проблема, которую следует рассмотреть, это время:

jobid = root.after(10, move, direction)

Время в 10 мс должно быть больше, чем время, необходимое для выполнения метода move(), плюс время для реакции. То есть, если вы не можете нарисовать поле минимального размера (10 x 10) без повторения на вашем пути, вам снова нужно вмешаться на этот раз.

Ниже приведена моя переделка вашего кода с использованием простого состояния переменная вместо идентификатора задания (плюс некоторые другие изменения.) Кажется, это решает проблему:

from tkinter import *
from turtle import RawTurtle, TurtleScreen

def showPos():
    monitor.delete('1.0', END)
    monitor.insert(END, "X: " + str(tool.ycor()) + " Z: " + str(tool.xcor()))

def goHome():
    tool.home()
    showPos()

def goUp():
    tool.sety(tool.ycor() + 10)

def goDown():
    tool.sety(tool.ycor() - 10)

def goRight():
    tool.setx(tool.xcor() + 10)

def goLeft():
    tool.setx(tool.xcor() - 10)

pressing = False

def start_move(event):
    global pressing

    event.widget.unbind('<ButtonPress-1>')  # unbind event handler inside handler(s)

    pressing = True

    move(event)

def stop_move(event):
    global pressing

    pressing = False

    event.widget.bind('<ButtonPress-1>', start_move)

def move(event):
    if not pressing:
        return

    direction = event.widget['text']

    if direction == '-X':
        goDown()
    elif direction == '+X':
        goUp()    
    elif direction == '-Z':
        goLeft()
    elif direction == '+Z':
        goRight()    

    showPos()

    root.after(75, move, event)

root = Tk()
root.title("CNC Lathe")

canvas = Canvas(root, width=800, height=600)
canvas.pack()

screen = TurtleScreen(canvas)
screen.bgcolor('black')
# screen.register_shape("wnmg.gif")

# tool = RawTurtle(screen, shape="wnmg.gif")
tool = RawTurtle(screen, shape='turtle')
tool.pencolor('white')

monitor = Text(root, height=1, width=16, font='Helvetica')
monitor.pack()

topFrame = Frame(root)
topFrame.pack()
middleFrame = Frame(root)
middleFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack()

for direction in ('-X', '+X', '-Z', '+Z'):
    if direction == '+X':
        button = Button(topFrame, text=direction)
        button.pack()

    if direction == '-X':
        button = Button(bottomFrame, text=direction)
        button.pack()

    if direction == '-Z':
        button = Button(middleFrame, text=direction)
        button.pack(side=LEFT)

    if direction == '+Z':
        button = Button(middleFrame, text=direction)
        button.pack(side=RIGHT)   

    button.bind('<ButtonPress-1>', start_move)
    button.bind('<ButtonRelease-1>', stop_move)

Button(middleFrame, text="Home", command=goHome).pack()

root.mainloop()

Я изменил курсор на черепаху, поскольку у меня не было вашего "wnmg.gif" изображения для работы с .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...