Создание и удаление виджетов являются довольно распространёнными заданиями, но большинство разработчиков не в восторге от него. Однако, wxPython способен значительно упростить данный процесс. Я сам неоднократно разрабатывал виджеты, основываясь на том, какие функции необходимы конечному пользователю программы, так что я могу ознакомить вас с массой вариантов. Например, администратор может получить дополнительные возможности, доступа к которым простые пользователи иметь не будут. В этом случае возникает ситуация, когда вам нужно быстро убрать или добавить административную панель с виджетами.
Я, к примеру, решил эту проблему очень просто. Это приложение даёт пользователям возможность добавлять и убирать кнопки, и ничего больше. Скрипт, который вы найдёте ниже, позволит вам создать окно, похожее на то, что вы видите в начале статьи. Когда вы нажмёте кнопку «Add» несколько раз, вы должны будете увидеть что-то вроде этого:
Как вы могли заметить, вы добавили несколько кнопок. Теперь давайте уделим мгновение и прочтём код. Я объясню этот код сразу же после того, как вы его прочтёте.
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 |
import wx class MyPanel(wx.Panel): def __init__(self, parent): """Constructor""" wx.Panel.__init__(self, parent) self.number_of_buttons = 0 self.frame = parent self.mainSizer = wx.BoxSizer(wx.VERTICAL) controlSizer = wx.BoxSizer(wx.HORIZONTAL) self.widgetSizer = wx.BoxSizer(wx.VERTICAL) self.addButton = wx.Button(self, label="Add") self.addButton.Bind(wx.EVT_BUTTON, self.onAddWidget) controlSizer.Add(self.addButton, 0, wx.CENTER|wx.ALL, 5) self.removeButton = wx.Button(self, label="Remove") self.removeButton.Bind(wx.EVT_BUTTON, self.onRemoveWidget) controlSizer.Add(self.removeButton, 0, wx.CENTER|wx.ALL, 5) self.mainSizer.Add(controlSizer, 0, wx.CENTER) self.mainSizer.Add(self.widgetSizer, 0, wx.CENTER|wx.ALL, 10) self.SetSizer(self.mainSizer) def onAddWidget(self, event): self.number_of_buttons += 1 label = "Button %s" % self.number_of_buttons name = "button%s" % self.number_of_buttons new_button = wx.Button(self, label=label, name=name) self.widgetSizer.Add(new_button, 0, wx.ALL, 5) self.frame.fSizer.Layout() self.frame.Fit() def onRemoveWidget(self, event): if self.widgetSizer.GetChildren(): self.widgetSizer.Hide(self.number_of_buttons-1) self.widgetSizer.Remove(self.number_of_buttons-1) self.number_of_buttons -= 1 self.frame.fSizer.Layout() self.frame.Fit() class MyFrame(wx.Frame): def __init__(self): """Constructor""" wx.Frame.__init__(self, parent=None, title="Add / Remove Buttons") self.fSizer = wx.BoxSizer(wx.VERTICAL) panel = MyPanel(self) self.fSizer.Add(panel, 1, wx.EXPAND) self.SetSizer(self.fSizer) self.Fit() self.Show() if __name__ == "__main__": app = wx.App(False) frame = MyFrame() app.MainLoop() |
Я думаю, что это довольно простой код, так что я сфокусирую ваше внимание на важных битах. Первая тема, о которой я хотел бы рассказать, это метод под названием Frame’s Fit(). Я обычно избегаю использования фита, но у меня были проблемы с изменением размера окна в момент добавления новых кнопок, и фит справился с этим. Стоит отметить, что фит постоянно пытается подогнать виджеты под окно, и, иногда, мне не нравится как это выглядит.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Как бы то ни было, следующий бит демонстрирует методы onAddWidget и onRemoveWidget. Обычно вам требуется два слоя: первый отвечает за размеры и обновления контейнера, второй за добавление и удаление виджетов. Весьма странно, но похоже, что фит делает это автоматически, так что вы можете смело удалять всё, что находится выше строки Layout(). Я убирал фиты, чтобы проверить, справится ли Layout с задачей подгона под контейнер, но как только я удалил фиты, размер контейнера перестал подстраиваться под количество кнопок, так что без фитов в данном случае не обойтись. Однако, если вы добавляете виджеты, которые точно поместятся в контейнере, вам будет достаточно и одного Layout.
В конце я хотел бы добавить небольшой комментарий. Вы также можете использовать Layout() в конце обновления Freeze / Thaw.
Подведем итоги
Благодаря этой статье вы должны научиться добавлять и удалять виджеты довольно быстро. Когда вы полностью освоите данное приложение, вы будете поражены его простотой и эффективностью. Это фрагмент информации, который я считаю очень полезным, так как сам пользуюсь данной техникой на протяжении многих лет.
Продолжение
Следующий урок №2: Как сделать скриншот вашего приложения
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»