Как получить тег фигуры при нажатии

#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. Я изменил принятый ответ на ответ Брайана в основном из-за простоты и потому, что именно его я буду использовать, тем не менее, еще раз спасибо за ваш ответ, и он работает так, как ожидалось.