Виджет Menu в tkinter
Меню – это виджет, который присутствует во многих пользовательских приложениях. Находится оно под строкой заголовка и представляет собой выпадающие списки под словами-пунктами меню. Пункты конечных списков представляют собой команды, обычно выполняющие какие-либо действия или открывающие диалоговые окна.
В tkinter
экземпляр меню создается от класса Menu
, далее его надо привязать к виджету, на котором оно будет расположено. Обычно таковым выступает главное окно приложения. Его опции menu
присваивается экземпляр Menu
через имя связанной с экземпляром переменной.
from tkinter import * root = Tk() mainmenu = Menu(root) root.config(menu=mainmenu) root.mainloop()
Если выполнить данный код, то никакого меню вы не увидите. Только тонкую полоску под заголовком окна, ведь ни одного пункта меню не было создано. Метод add_command
добавляет пункт меню:
mainmenu.add_command(label='Файл') mainmenu.add_command(label='Справка')
В данном случае "Файл" и "Справка" – это команды. К ним можно добавить опцию command
, связав тем самым с какой-либо функцией-обработчиком клика. Хотя такой вариант меню имеет право на существование, в большинстве приложений панель меню содержит выпадающие списки команд, а сами пункты на панели командами по сути не являются. Клик по ним приводит лишь к раскрытию соответствующего списка.
В Tkinter проблема решается созданием новых экземпляров Menu
и подвязыванием их к главному меню с помощью метода add_cascade
.
from tkinter import * root = Tk() mainmenu = Menu(root) root.config(menu=mainmenu) filemenu = Menu(mainmenu, tearoff=0) filemenu.add_command(label="Открыть...") filemenu.add_command(label="Новый") filemenu.add_command(label="Сохранить...") filemenu.add_command(label="Выход") helpmenu = Menu(mainmenu, tearoff=0) helpmenu.add_command(label="Помощь") helpmenu.add_command(label="О программе") mainmenu.add_cascade(label="Файл", menu=filemenu) mainmenu.add_cascade(label="Справка", menu=helpmenu) root.mainloop()
На основное меню mainmenu, добавляются не команды, а другие меню. У filemenu и helpmenu в качестве родительского виджета указывается не root, а mainmenu. Команды добавляются только к дочерним меню. Значение 0 опции tearoff
отключает возможность открепления подменю, иначе его можно было бы делать плавающим кликом мыши по специальной линии. В случае tearoff=0
она отсутствует.
Точно также можно подвязывать дочерние меню к filemenu и helpmenu, создавая многоуровневые списки пунктов меню.
helpmenu = Menu(mainmenu, tearoff=0) helpmenu2 = Menu(helpmenu, tearoff=0) helpmenu2.add_command(label="Локальная справка") helpmenu2.add_command(label="На сайте") helpmenu.add_cascade(label="Помощь",menu=helpmenu2) helpmenu.add_command(label="О программе")
Метод add_separator
добавляет линию разделитель в меню. Используется для визуального разделения групп команд.
В tkinter
можно создать всплывающее меню, оно же контекстное (если настроить его появление по клику правой кнопкой мыши). Для этого экземпляр меню подвязывается не через опцию menu
к родительскому виджету, а к меню применяется метод post
, аргументами которого являются координаты того места, где должно появляться меню.
from tkinter import * def circle(): c.create_oval(x, y, x + 30, y + 30) def square(): c.create_rectangle(x, y, x + 30, y + 30) def triangle(): c.create_polygon(x, y, x - 15, y + 30, x + 15, y + 30, fill="white", outline="black") def popup(event): global x, y x = event.x y = event.y menu.post(event.x_root, event.y_root) x = 0 y = 0 root = Tk() c = Canvas(width=300, height=300, bg="white") c.pack() c.bind("<Button-3>", popup) menu = Menu(tearoff=0) menu.add_command(label="Круг", command=circle) menu.add_command(label="Квадрат", command=square) menu.add_command(label="Треугольник", command=triangle) root.mainloop()
Здесь при клике на холсте правой кнопкой мыши в этой точке всплывает меню. При выборе пункта меню рисуется соответствующая фигура в этом же месте.
Практическая работа
Измените программу из практической работы предыдущего урока так, чтобы открытие и сохранение файлов выполнялось не через экземпляры Button
, а через Menu
. Команду очистки текстового поля поместите в контекстное меню.
Курс с примерами решений практических работ: pdf-версия