Набор инструментов wxPython обзавёлся контекстными менеджерами несколько лет тому назад, но, по каким-то причинам, примеров их использования в приложениях можно найти лишь несколько. В данной статье мы рассмотрим 3 примера контекстных менеджеров в wxPython. Начнём мы с написания собственного контекстного менеджера, а затем рассмотрим несколько встроенных в wxPython вариантов.
Создание вашего собственного контекстного менеджера в wxPython
Создать собственный контекстный менеджер в wxPython достаточно просто. Мы будем использовать wx.FileDialog в нашем примере контекстного менеджера.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import os import wx class ContextFileDialog(wx.FileDialog): """""" def __enter__(self): """""" return self def __exit__(self, exc_type, exc_val, exc_tb): self.Destroy() |
В данном примере мы превращаем wx.FileDialog в подкласс, а затем просто избавляемся от методов __enter__ и __exit__. Это превратит нашу инстанцию FileDialog в контекстный менеджер, в случаях, когда мы вызываем его посредством утверждения with, дотсупного в wxPython. Давайте добавим пару строк кода, чтобы утилизировать нашу абсолютно новую версию File Dialog.
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 |
class MyPanel(wx.Panel): """""" def __init__(self, parent): """Constructor""" wx.Panel.__init__(self, parent) btn = wx.Button(self, label='Open File') btn.Bind(wx.EVT_BUTTON, self.onOpenFile) def onOpenFile(self, event): """""" wildcard = "Python source (*.py)|*.py|" \ "All files (*.*)|*.*" kwargs = {'message':"Choose a file", 'defaultDir':os.path.dirname(os.path.abspath( __file__ )), 'defaultFile':"", 'wildcard':wildcard, 'style':wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR } with ContextFileDialog(self, **kwargs) as dlg: if dlg.ShowModal() == wx.ID_OK: paths = dlg.GetPaths() print "You chose the following file(s):" for path in paths: print path class MyFrame(wx.Frame): """""" def __init__(self): """Constructor""" wx.Frame.__init__(self, None, title='wxPython Contexts') panel = MyPanel(self) self.Show() if __name__ == '__main__': app = wx.App(False) frame = MyFrame() app.MainLoop() |
Взгляните на код в MyPanel. Здесь вы можете увидеть использование нами утверждения with, дотсупного в wxPython, в хендлере событий onOpenFile вне класса MyPanel. Теперь же давайте продвинемся вперёд и взглянем на некоторые встроенные в wxPython примеры.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Контекстный менеджер wxPython
Пакет wxPython поддерживает контекстные менеджеры во всём, что является подклассом wx.Dialog, а также в следующих виджетах:
- BusyInfo
- BusyCursor
- WindowDisabler
- LogNull
- DCTextColourChanger
- DCPenChanger
- DCBrushChanger
- DCClipper
- Freeze / wx.Thaw
Возможно, есть и другие, но в этом списке собрано большинство виджетов, обладающих подобной возможностью. Давайте взглянем на несколько примеров:
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 |
import time import wx class MyPanel(wx.Panel): """""" def __init__(self, parent): """Constructor""" wx.Panel.__init__(self, parent) self.frame = parent main_sizer = wx.BoxSizer(wx.VERTICAL) dlg_btn = wx.Button(self, label='Open ColorDialog') dlg_btn.Bind(wx.EVT_BUTTON, self.onOpenColorDialog) main_sizer.Add(dlg_btn, 0, wx.ALL|wx.CENTER) busy_btn = wx.Button(self, label='Open BusyInfo') busy_btn.Bind(wx.EVT_BUTTON, self.onOpenBusyInfo) main_sizer.Add(busy_btn,0, wx.ALL|wx.CENTER) self.SetSizer(main_sizer) def onOpenColorDialog(self, event): """ Создаёт и открывает wx.ColourDialog """ with wx.ColourDialog(self) as dlg: if dlg.ShowModal() == wx.ID_OK: data = dlg.GetColourData() color = str(data.GetColour().Get()) print 'You selected: %s\n' % color def onOpenBusyInfo(self, event): """ Создаёт и открывает инстанцию BusyInfo """ msg = 'This app is busy right now!' self.frame.Hide() with wx.BusyInfo(msg) as busy: time.sleep(5) self.frame.Show() class MyFrame(wx.Frame): """""" def __init__(self): """Constructor""" wx.Frame.__init__(self, None, title='Context Managers') panel = MyPanel(self) self.Show() if __name__ == '__main__': app = wx.App(False) frame = MyFrame() app.MainLoop() |
В коде, который вы видите сверху, есть 2 примера контекстных менеджеров wxPython. Первый в хендлере событий под названием onOpenColorDialog. Здесь мы создаём инстанцию из wx.ColourDialog, а затем извлекаем нужный цвет, если пользователь нажмёт кнопку «ОК». Второй пример немного сложнее лишь в том, что он прячет (фрейм) рамку перед отображением инстанции BusyInfo. Честно говоря, я думаю, что второй пример может быть улучшен помещением задачи с появлением и скрыванием рамки в сам контекстный менеджер, но я оставлю его нетронутым, чтобы мои читатели могли немного поупражняться.
Итоги
Контекстные менеджеры wxPython достаточно удобны и просты в использовании. Я надеюсь, что когда-то вы примените их в своём коде. Чтобы убедиться в этом, испробуйте и другие контекстные менеджеры wxPython, кроме тех, что мы рассматривали в примерах. Вдруг, они идеально подойдут вашей базе кодов или просто сделают ваш код немного чище.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»