2010-08-31 1 views
1

Следующая строка python свяжет метод «click» с событием, когда пользователь нажимает кнопку на кнопку мыши, пока указатель находится на виджетах; независимо от того, где указатель, когда она отпускает кнопку.Как указать полный щелчок в Python Tkinter

self.bind('<Button-1>',self.click) 

Если я использую «ButtonRelease» вместо «Button» в коде, это кажется, что метод «щелчок» будет вызываться для виджета , на котором была нажата кнопкой мыши после отпускания кнопки; независимо от того, где вы его выпускаете.

1- Не существует опрятного способа заставить его вызвать связанный метод, только если кнопка мыши была выпущена на моем виджетах; независимо от того, где он был нажат?

2- Не существует ли аккуратного способа сказать, что он реагирует только в случае полного щелчка (нажмите и отпустите оба на том же виджете)?

ответ

5

1- Нет ли изящный способ сделать это назвать связанный метод, только если кнопка мыши была выпущена на моем виджетах; вне зависимости от ситуации нажав?

2- Не существует отличный способ сказать это реагировать только в случае полного нажмите (нажать и отпустить обе на одной и той же виджета)?

Нет «аккуратный» путь, потому что, как Tkinter-х docs говорят:

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

и оба ваши желания несовместимы с этой автоматической захватывая указателя мыши на пресс-вниз (который я не знаю, как отключить - я думаю, что это может быть невозможно отключить, но доказать отрицательное трудно;-).

Таким образом, вам нужно больше работы и не «опрятное» решение: при обратном вызове события кнопки-кнопки свяжите события ввода и опуска (привязанные методы экземпляра класса, в которых вы можете отслеживать, является ли мышь в настоящее время внутри или внутри интересующего виджета) этого окна, а также кнопки-релиза; таким образом, когда приходит событие релиза, вы знаете, следует ли выполнять «фактический обратный вызов приложения» (если внутри) или ничего не делать (если есть на улице) - это дает вам ваше желание номер 2, но описание этого как аккуратного будет растягиваться ,

Желание номер 1 еще сложнее, потому что вам нужно отслеживать ввод и оставлять события на интересующем виджет КАЖДЫЙ - недостаточно знать один бит, находится ли мышь внутри или снаружи, но вы должны отслеживать какой виджет (если таковой имеется) находится в данный момент, для правильного «фактического обратного вызова приложения» (если вообще) в момент отпускания кнопки.

В то время как внутренние не собираются быть аккуратным, каждая функция может быть связан в один аккуратный-to-вызов функции ... с немного «indaginous» внутренностей (термин, который используется чаще для обозначения корня работа канала или что-то подобное, а не программирование, но может быть уместным, когда вы хотите идти против зерен функциональности, жестко закодированной в рамках ... это недостаток фреймворков - вы в клевере, пока вы хотите вести себя так, как они поддерживают, но когда вы захотите победить свое обычное поведение, чтобы сделать что-то совершенно другое, что едва ли может быть «опрятным»!).

+1

Я не думаю, что это довольно сложно, как вы заставляете его звучать. В вашем обратном вызове вы можете просто спросить Tkinter для виджета под курсором, а не отслеживать все события ввода и выхода. См. 'Winfo_containing'. –

1

Связывание с ButtonRelease-1 не достаточно. Обратный вызов не срабатывает до тех пор, пока кнопка не будет отпущена, но не имеет значения, где находится мышь, когда она отпущена. То, что управляет, - это то, где мышь была, когда она была нажата, как сказал Алекс Мартелли. Легкий способ получить желаемое поведение - положить все на холст и привязать обратный вызов к ButtonRelease-1. Теперь у вас есть что-то вроде

def callback(event): 
    x1, y1, x2, y2 = canvas.bbox(widget) 
    if x1 <= event.x <= x2 and y1 <= event.y <= y2: 
     <whatever> 

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

+1

С помощью обычных виджетов вы можете использовать 'winfo_containing', чтобы получить имя виджета под курсором. Не нужно прибегать к использованию холста, если нет других причин для этого. –