#python #events #user-interface #click #tkinter
#python #Мероприятия #пользовательский интерфейс #нажмите #tkinter
Вопрос:
Допустим, я создал холст в приложении Tkinter.
На холсте я нарисовал несколько прямоугольников.
По сути, я хочу знать, в каком прямоугольнике пользователь нажал, это моя главная забота, но это то, что я пробовал, и что, по моему мнению, может быть решением.
Это мой макет:
for x in range(1,6):
for y in range(1,7):
tableNumber = y 6*(x-1)
w.create_rectangle((table.xSeparation table.width) * y - table.width,
(table.ySeparation table.height) * x - table.height,
(table.xSeparation table.width)*y,
(table.ySeparation table.height) * x,
fill="brown", tags="table" str(tableNumber))
w.tag_bind("table" str(tableNumber), '<Button-1>', do)
Таким образом, это просто создает прямоугольники в макете строк и столбцов.
У каждого прямоугольника есть определенный тег в форме table1
, table2
to table30
.
Когда я нажимаю на прямоугольник, do
функция выполняется.
Допустим, do было что-то вроде:
def do(event):
print "click"
Я не получаю «щелчок» в консоли для каждого щелчка в прямоугольнике.
Я хотел бы иметь возможность получить тег выбранного прямоугольника, чтобы иметь возможность делать что-то подобное:
def do(event):
print str(theTagOfTheClickedRectangle)
Итак, я проверил, какие события я могу вызвать, которые:
- виджет
- x, y
- x_root, y_root
- символ
- keysym
- код ключа
- число
- ширина, высота
- Тип
Ни один из них, похоже, не указывает, какой прямоугольник я щелкнул.
Я думал о добавлении дополнительных параметров к do
функции здесь:
w.tag_bind("table" str(tableNumber), '<Button-1>', do(event, tag))
Но, похоже, это не работает нормально, но, возможно, я делаю неправильно do
:
do(event, tag): #this doesn't work at all!!
print event.x
print tag
Я надеюсь, что вопрос ясен, если бы я получил тег таким же образом, как я могу получить ‘x’ и ‘y’ события, это было бы очень удобно.
Единственное реальное решение, о котором я могу сейчас подумать, — это вычислить математику ‘event.x’ и ‘event.y’ и вычислить, основываясь на координатах щелчка, на каком прямоугольнике нажал пользователь, это кажется слишком сложным для того, что я пытаюсь сделать, хотя яделал это раньше, и это, очевидно, работает.
Я надеюсь, что вопрос ясен, в противном случае, пожалуйста, попросите каких-либо разъяснений.
Обратите внимание, что я не привязан ни к одному из этого кода, скорее, я ищу решение этой проблемы, наиболее эффективное будет работать, даже если означает не работать с тегами, или другим типом виджета, или что-то еще проще.
Ответ №1:
Вы можете использовать что-то вроде этого, чтобы ссылаться на объект, на который нажали:
event.widget.find_withtag("current")
Тег «текущий» является специальным и представляет самый верхний объект под мышью.
Комментарии:
1. Спасибо @Bryan! Это очень простое и правильное решение! Я проверил ваш профиль, и вы, кажется, довольно много знаете о tkinter. Могу я спросить, какую документацию вы используете регулярно? Мне нравится простота tkinter, но я нахожу документацию по нему очень неполной. Например, то, что вы предложили в качестве ответа, никогда не упоминалось ни в одной из использованных мной документов. Большое вам спасибо!
2. @Trufa: окончательным сайтом для получения информации, связанной с tk toolkit, являются официальные справочные страницы по адресу tcl.tk/man/tcl8.5/TkCmd/contents.htm . Они специфичны для языка Tcl, но адаптировать информацию к tkinter очень просто. Для получения информации, относящейся к tkinter, перейдите по effbot.org/tkinterbook (и «текущий» тег упоминается на этом сайте FWIW). Один из последних сайтов с некоторой полезной информацией tkdocs.com который имеет покрытие python, perl, tcl и ruby.
3. спасибо за это! Я не знал о Tcl, я проверю это, другие — это те, которые обычно появляются в поиске Google. Я не могу поверить, что пропустил «текущий» в списке, вероятно, потому, что я не знал, что искал. В любом случае, еще раз спасибо!!
Ответ №2:
w.tag_bind("table" str(tableNumber), '<Button-1>', do(event, tag))
должен быть изменен на
tag = "table" str(tableNumber)
callback = lambda event, tag=tag: do(event, tag)
w.tag_bind(tag, '<Button-1>', callback)
Лямбда-выражение создает функцию с именем тега в качестве значения по умолчанию второго аргумента. Tkinter вызывает эту функцию только с одним аргументом, событием, а второй аргумент использует значение по умолчанию.
Комментарии:
1. Это чертовски круто!! Это работает как шарм, и это именно то, что я искал! Большое вам спасибо! Единственное, что я хотел бы спросить, если вы можете немного объяснить мне, что вы сделали там в этой строке
callback = lambda event, tag=tag: do(event, tag)
, меня немного смущает эта лямбда-функция. Еще раз большое вам спасибо!2. Это эквивалентно
def callback(event, t=tag): return do(event, t)
.3. Я изменил принятый ответ на ответ Брайана в основном из-за простоты и потому, что именно его я буду использовать, тем не менее, еще раз спасибо за ваш ответ, и он работает так, как ожидалось.