Вы когда-нибудь интересовались тем, как создавать маленькие иконки в трэе Windows, которые будут отображаться в нижнем правом углу экрана? Набор инструментов wxPython предлагает простой способ реализации данной возможности, а эта статья написана специально для того, чтобы научить вас этому.
Однако сначала вам нужно будет найти иконку или создать файл изображения Python посредством утилиты img2py. Я описывал как это сделать в статье «Вставляем иконку в строку заголовка».
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Создание иконки панели задач в Classic
Создание подкласса TaskBarIcon является первым необходимым шагом. Это несложно, вам нужно только выбрать подходящие методы, которые позволят иконке отображаться корректно. Давайте взглянем на простой пример для wxPython Classic:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import wx class PythonIcon(wx.TaskBarIcon): TBMENU_RESTORE = wx.NewId() TBMENU_CLOSE = wx.NewId() TBMENU_CHANGE = wx.NewId() TBMENU_REMOVE = wx.NewId() def __init__(self, frame): wx.TaskBarIcon.__init__(self) self.frame = frame # Задаём изображение icon = wx.Icon('python.ico', wx.BITMAP_TYPE_ICO) self.SetIcon(icon, "Python") # Биндим некоторые события self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE) self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.OnTaskBarLeftClick) def CreatePopupMenu(self, evt=None): """ Данный метод называется в зависимости от базового класса, когда вам нужно сделать из меню поп-ап для стандартного события EVT_RIGHT_DOWN. Просто создайте такое меню, как вы хотите, а затем перезапустите его из этой функции, а базовый класс позаботится обо всём остальном. """ menu = wx.Menu() menu.Append(self.TBMENU_RESTORE, "Open Program") menu.Append(self.TBMENU_CHANGE, "Show all the Items") menu.AppendSeparator() menu.Append(self.TBMENU_CLOSE, "Exit Program") return menu def OnTaskBarActivate(self, evt): """""" pass def OnTaskBarClose(self, evt): """ Удалите иконку панели задач и рамку из самой иконки панели задач """ self.frame.Close() def OnTaskBarLeftClick(self, evt): """ Создайте меню, которое будет вызываться правой кнопкой мыши """ menu = self.CreatePopupMenu() self.PopupMenu(menu) menu.Destroy() |
Первый класс основан на том, который вы могли встретить в демонстрационном пакете wxPython. Как я уже упоминал ранее, вы заметите, что мы превращаем wx.TaskBarIcon в подкласс. Мы прикрепляем его иконку к чему-либо, а затем добавляем вспомогательный стринг, который будет отображаться при наведении мыши.
То есть, когда вы будете наводить мышку на иконку в панели задач, будет появляться текст. Затем мы биндим несколько событий. Первое событие будет вызывать поп-ап меню при нажатии правой кнопкой мыши. Да, я знаю, что он показывает, что мы биндили его к нажатию левой кнопкой мыши, но в данном случае это так не работает.
В любом случае, мы настраиваем его так, что при нажатии правой кнопкой мыши пользователю предоставляется несколько опций на выбор. Да, нам доступна лишь пара опций, но это хотя бы что-то. Вы заметите, что мы вызываем метод фрейма Close, чтобы закрыть этот фрейм.
Давайте добавим сам класс, который будет убирать иконку из панели задач:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class MyForm(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, title="TaskBarIcon Tutorial", size=(500,500)) panel = wx.Panel(self) self.tbIcon = PythonIcon(self) self.Bind(wx.EVT_CLOSE, self.onClose) def onClose(self, evt): """ Уничтожает иконку панели задач и рамку """ self.tbIcon.RemoveIcon() self.tbIcon.Destroy() self.Destroy() if __name__ == "__main__": app = wx.App(False) frame = MyForm().Show() app.MainLoop() |
Здесь мы просто подтверждаем класс TaskBarIcon, который мы создали раньше и биндим рамку к EVT_CLOSE. Вас это может удивить. Есть несколько интересных фишек, связанных с использованием панели задач Windows. Если я просто прикажу рамке закрыться, то она закроется нормально, но вот иконка останется и Python вообще ничего не собирается с этим делать.
Если вы хотите просто разрешить пользователю закрыть приложение используя меню, которое выпадает при нажатии правой кнопки мыши на иконку панели задач, тогда вы можете просто добавить метод RemoveIcon и self.Destroy(), и всё будет работать как следует (по каким-то причинам метода RemoveIcon недостаточно для того, чтобы избавиться от TaskBarIcon, так что вам нужно будет в добавок приказать ей себя уничтожить.
Но если пользователь может выйти из приложения ещё и посредством нажатия маленького крестика в верхнем правом углу окна, тогда вам нужно будет обнаружить процесс EVT_CLOSE, и приказать приложение обработать его. Когда вы обнаруживаете данное событие, вы НЕ можете просто вызывать self.Close(), так как это запустит бесконечный цикл. Поэтому мы делаем выбор в пользу self.Destroy().
Создаём иконку панели задач в Phoenix
Создание иконки панели задач в Phoenix значительно отличается от аналогичного процесса в Classic. Причина этому – перемещение класса TaskBarIcon в wx.adv. Для того, чтобы вы до конца всё поняли, я добавляю пример, который был обновлён таким образом, чтобы он запускался в Phoenix:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
import wx import wx.adv class PythonIcon(wx.adv.TaskBarIcon): TBMENU_RESTORE = wx.NewId() TBMENU_CLOSE = wx.NewId() TBMENU_CHANGE = wx.NewId() TBMENU_REMOVE = wx.NewId() def __init__(self, frame): wx.adv.TaskBarIcon.__init__(self) self.frame = frame # Задаём изображение icon = wx.Icon('python.ico', wx.BITMAP_TYPE_ICO) self.SetIcon(icon, "Python") # Биндим некоторые процессы self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE) self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.OnTaskBarLeftClick) def CreatePopupMenu(self, evt=None): """ Данный метод называется в честь базового класса, когда вам нужно сделать из меню поп-ап Для стандартного события EVT_RIGHT_DOWN. Просто создайте такое меню, как вы хотите, а затем перезапустите его из этой функции, а базовый класс позаботится обо всём остальном. """ menu = wx.Menu() menu.Append(self.TBMENU_RESTORE, "Open Program") menu.Append(self.TBMENU_CHANGE, "Show all the Items") menu.AppendSeparator() menu.Append(self.TBMENU_CLOSE, "Exit Program") return menu def OnTaskBarActivate(self, evt): """""" pass def OnTaskBarClose(self, evt): """ Уничтожает иконку панели задач и её рамку в самой иконке панели задач """ self.frame.Close() def OnTaskBarLeftClick(self, evt): """ Создаёт меню, которое появляется при нажатии правой кнопкой мыши """ menu = self.CreatePopupMenu() self.PopupMenu(menu) menu.Destroy() class MyForm(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, title="TaskBarIcon Tutorial", size=(500,500)) panel = wx.Panel(self) self.tbIcon = PythonIcon(self) self.Bind(wx.EVT_CLOSE, self.onClose) def onClose(self, evt): """ Уничтожает иконку панели задач и её рамку """ self.tbIcon.RemoveIcon() self.tbIcon.Destroy() self.Destroy() if __name__ == "__main__": app = wx.App(False) frame = MyForm().Show() app.MainLoop() |
Главным отличием является то, что здесь мы импортируем wx.adv, и используем его, когда мы определяем и инициализируем TaskBarIcon. Второе отличие – биндинг EVT_TASKBAR_LEFT_DOWN, который также был перемещён в wx.adv. В остальном код остаётся прежним и работает как положено.
Итоги
Теперь вы можете добавить в своё приложение иконку панели задач. Я настоятельно рекомендую ознакомится с демо-пакетом wxPython, чтобы узнать какие ещё операций с иконкой вам доступны. Я считаю, что добавление иконки панели задач в ваше приложение делает его более удобным, особенно если вам нужно переводить его в фоновый режим, а затем запускать, когда пользователю оно понадобится.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»