В один прекрасный день я наткнулся на обсуждение на StackOverflow, в рамках которого парень пытался выяснить как открывать саб-фрейм лишь единожды. Проще говоря, он хотел, чтобы это происходило с одной инстанцией саб-фрейма (и другими саб-фреймами). После короткого поиска в Google, я нашёл старую тему в Google-группе wxPython, содержащую интересное решение для данной задачи.
На самом деле нужно немного мета-программирования, но упражнение довольно интересное, так что я решил поделится им с читателями моего сайта. Вот код:
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 |
import wx class MyPanel(wx.Panel): """""" def __init__(self, parent): """Constructor""" wx.Panel.__init__(self, parent) class SingleInstanceFrame(wx.Frame): """""" instance = None init = 0 def __new__(self, *args, **kwargs): """""" if self.instance is None: self.instance = wx.Frame.__new__(self) elif not self.instance: self.instance = wx.Frame.__new__(self) return self.instance def __init__(self): """Constructor""" print(id(self)) if self.init: return self.init = 1 wx.Frame.__init__(self, None, title="Single Instance Frame") panel = MyPanel(self) self.Show() class MainFrame(wx.Frame): """""" def __init__(self): """Constructor""" wx.Frame.__init__(self, None, title="Main Frame") panel = MyPanel(self) btn = wx.Button(panel, label="Open Frame") btn.Bind(wx.EVT_BUTTON, self.open_frame) self.Show() def open_frame(self, event): frame = SingleInstanceFrame() if __name__ == '__main__': app = wx.App(False) frame = MainFrame() app.MainLoop() |
Изюминкой данного кода является класс SingleInstanceFrame и его метод __new__ в частности. Здесь мы можем проверить была ли переменная self.instance задана как None. Если да, мы создаём новую инстанцию.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Мы также создаём новую инстанцию в случае, если пользователь закрывает рамку. Для этого и нужно утверждение elif. Оно используется для проверки того, была ли инстанция удалена, и, если она была удалена, создаёт новую инстанцию.
Вы также заметите, что у нас есть переменная, которая называется self.init. Она нужна для проверки того, была ли инстанция инициализирована. Если была, __init__ просто вернёт, вместо того, чтобы повторно инстанцинировать всё. В любом случае, я надеюсь, что данный пример был для вас поучительным.
Итоги
Эта статья демонстрирует шаблон проектирования, который принято называть одиночка. Он достаточно эффективен для решения поставленных задач. Если вы хотите, чтобы после нажатия кнопки открывалась лишь одна рамка, использование «одиночки» отлично подойдёт.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»