Tkinter: получает координаты мыши только при нажатии кнопки мыши

#python #button #events #tkinter #motion

#python #кнопка #Мероприятия #tkinter #движение

Вопрос:

У меня есть довольно конкретный вопрос в Python.

Я знаю решение для постоянного получения координат мыши в кадре в Tkinter:

 import Tkinter as tk
root = tk.Tk()

def motion(event):
    x, y = event.x, event.y
    print('{}, {}'.format(x, y))

root.bind('<Motion>', motion)
root.mainloop()
  

Теперь мой вопрос заключается в объединении нажатой кнопки и события движения.
В двух словах: я хочу, чтобы координаты мыши отображались только при нажатии кнопки, а не когда она отпущена или не нажата.

 def ButtonPress(event):
    #This is the part, where I can't figure out, how to proceed.
    #How can I call the motion event from here.


Bt = Button(root, text='Press for coordinates!')
Bt.bind('<ButtonPress>', ButtonPress)

  

С уважением!

Комментарии:

1. Зачем вам нужно событие движения? Информация содержится в самом событии. скопируйте и вставьте код в свою функцию и попробуйте.

Ответ №1:

Есть по крайней мере два очень простых решения:

  • установите / снимите флаг при нажатии / отпускании кнопки, а в вашей функции выводите координаты только в том случае, если флаг установлен,
  • привязать / отменить привязку события движения при нажатии / отпускании кнопки.

Установка флага

В этом примере используется флаг с именем do_capture , значение которого устанавливается True при нажатии кнопки и устанавливается False при отпускании кнопки:

 import Tkinter as tk
root = tk.Tk()

def motion(event):
    if do_capture:
        x, y = event.x, event.y
        print('{}, {}'.format(x, y))

def capture(flag):
    global do_capture
    do_capture = flag

root.bind('<Motion>', motion)
root.bind("<ButtonPress-1>", lambda event: capture(True))
root.bind("<ButtonRelease-1>", lambda event: capture(False))

capture(False)

root.mainloop()
  

Привязать / отменить привязку

В этом примере мы привязываем <Motion> событие при нажатии кнопки и отменяем его при отпускании:

 import Tkinter as tk
root = tk.Tk()

def motion(event):
    x, y = event.x, event.y
    print('{}, {}'.format(x, y))

def capture(flag):
    if flag:
        root.bind('<Motion>', motion)
    else:
        root.unbind('<Motion>')

root.bind("<ButtonPress-1>", lambda event: capture(True))
root.bind("<ButtonRelease-1>", lambda event: capture(False))

root.mainloop()
  

Комментарии:

1. Ну, это вроде как работает! Теперь я создал прямоугольник размером 50×50 пикселей в tinkter и хочу активировать эту привязку только при наведении курсора мыши на этот прямоугольник. Есть ли решение, при котором я могу объединить привязку с информацией о том, где прямоугольник помещен в рамку?

Ответ №2:

Если вы не хотите сохранять положение мыши в обратном вызове движения, а затем повторно считывать его в обратном вызове кнопки, вы можете использовать winfo_pointer() , чтобы получить абсолютное положение указателя на экране и вычесть положение окна winfo_root() , чтобы получить положение указателя относительно окна.

Конечно, вам нужно будет самостоятельно отслеживать положение указателей за пределами окна.