Виджет фрейма от wxPython, используется практически во всех приложениях, написанных с помощью данного пакета инструментов. В нём есть кнопки для сворачивания, полноэкранного режима и закрытия, а также строка, содержащая информацию о приложении. wx.Frame позволяет вам управлять данным виджетом, а также удалять и редактировать как кнопки, так и надписи. В данной статье мы рассмотрим несколько способов изменения поведения виджета wx.Frame. В частности, мы рассмотрим следующие аспекты:
- Разные способы создания стандартной рамки
- Как создать рамку без надписи (то есть без строки заголовка)
- Как создать рамку с отключённой кнопкой закрытия
- Как создать рамку без кнопок «Свернуть» и «Развернуть»
- Как создать рамку, размер которой нельзя изменить
- Как создать рамку без системного меню
- Как сделать так, чтобы ваша рамка отображалась поверх остальных окон
Приступая к работе
Начать с истоков, то есть изучить поведение стандартной рамки, чтобы понять какие изменения возможны. Так что давайте начнём со стандартного стиля рамки wx.DEFAULT_FRAME_STYLE. Вы можете создать рамку, которая использует wx.DEFAULT_FRAME_STYLE (или его эквивалент) тремя разными способами. Первый и самый простой – сделать что-то вроде этого:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import wx class DefaultFrame(wx.Frame): """ Стандартная рамка """ def __init__(self): """Constructor""" wx.Frame.__init__(self, None, title="Default Frame") panel = wx.Panel(self) self.Show() if __name__ == "__main__": app = wx.App(False) frame = DefaultFrame() app.MainLoop() |
Мы создадим стандартную рамку, обладающую функциональностью, привычной каждому пользователю. Теперь же давайте значительно изменим её, используя wx.DEFAULT_FRAME_STYLE.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import wx class DefaultFrame(wx.Frame): """ Стандартная рамка """ def __init__(self): """Constructor""" wx.Frame.__init__(self, None, title="Default Frame", style=wx.DEFAULT_FRAME_STYLE) panel = wx.Panel(self) self.Show() if __name__ == "__main__": app = wx.App(False) frame = DefaultFrame() app.MainLoop() |
Данный код делает АБСОЛЮТНО то же самое, что и предыдущий. Теперь, если вы немного покопаетесь в коде, вы выясните, что wx.DEFAULT_FRAME_STYLE по сути выглядит именно так, то есть является комбинацией данных элементов:
1 2 |
wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN |
Так что давайте ещё раз изменим код, чтобы понять, как это работает.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import wx class DefaultFrame(wx.Frame): """ Стандартная рамка """ def __init__(self): """Constructor""" default = (wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN) wx.Frame.__init__(self, None, title="Default Frame", style=default) panel = wx.Panel(self) self.Show() if __name__ == "__main__": app = wx.App(False) frame = DefaultFrame() app.MainLoop() |
Это было просто. Теперь вы готовы экспериментировать!
Создаём рамку без надписи
Давайте создадим рамку, которая не имеет подписи. Подпись – это то, что содержит название приложения, кнопки сворачивания, разворачивания или закрытия, и располагает в верхней части окна.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import wx class NoCaptionFrame(wx.Frame): """""" def __init__(self): """Constructor""" no_caption = (wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CLOSE_BOX | wx.CLIP_CHILDREN) wx.Frame.__init__(self, None, title="No Caption", style=no_caption) panel = wx.Panel(self) self.Show() if __name__ == "__main__": app = wx.App(False) frame = NoCaptionFrame() app.MainLoop() |
Когда это код будет запущен, панель сожмётся в верхнем левом углу рамки. Вы можете изменить код так, чтобы панель располагалась в другом месте, но это будет выглядеть ужасно странно. Вам также стоит помнить, что это приложение нельзя закрыть, так как самой кнопки «Закрыть» попросту нет. Так что вам нужно будет снять процесс Python, чтобы закрыть данное приложение.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Создаём рамку с отключённой кнопкой «Закрыть»
Некоторым программистам бывает нужна рамка с отключённой кнопкой «Закрыть». На Windows, вы не можете удалить эту кнопку, но при этом оставить все остальные, но вы можете её деактивировать. Нa Linux эта кнопка действительно удаляется. Вот сам код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import wx class NoCloseFrame(wx.Frame): """ Данная рамка не имеет кнопки «Закрыть», меню «Закрыть» также деактивировано """ def __init__(self): """Constructor""" no_close = (wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLIP_CHILDREN) wx.Frame.__init__(self, None, title="No Close", style=no_close) panel = wx.Panel(self) self.Show() if __name__ == "__main__": app = wx.App(False) frame = NoCloseFrame() app.MainLoop() |
Конечно, на Windows, у вас просто не останется других способов закрыть приложение, так что данный момент будет раздражать пользователей. Может, место стандартного крестика, вы захотите добавить wx.Button, которая выполнит его роль. В Linux, вы сможете выйти из приложения посредством двойного клика в верхнем левом углу.
Создаём рамку без кнопок «Свернуть» и «Развернуть»
Иногда, вам нужно создать приложение, которое нельзя будет свернуть или развернуть. Раз уж мы зашли так далеко, то давайте создадим приложение, которое не будет отображаться в панели задач!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import wx class NoMaxMinFrame(wx.Frame): """ У данной рамки нет кнопок «Свернуть» и «Развернуть». """ def __init__(self): """Constructor""" no_caption = (wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN | wx.FRAME_NO_TASKBAR) wx.Frame.__init__(self, None, title="No Max/Min", style=no_caption) panel = wx.Panel(self) self.Show() if __name__ == "__main__": app = wx.App(False) frame = NoMaxMinFrame() app.MainLoop() |
Как вы видите, мы просто удалили флажки стиля wx.MINIMIZE_BOX и wx.MAXIMIZE_BOX, а также добавили флажок стиля wx.FRAME_NO_TASKBAR. На Windows 7 это работает отлично, но на Linux и Mac OS я заметил, что кнопка «Развернуть» не была удалена.
Создаём рамку, размер которой нельзя изменить
В теории, вам может понадобится создать рамку, размер которой нельзя изменить. Вы можете использовать SetSizeHints или же несколько флажков стиля рамки. Вот пример того, как реализовать последнее:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import wx class NoResizeFrame(wx.Frame): """ Размер рамки не может быть изменён. Её можно только свернуть и закрыть """ def __init__(self): """Constructor""" no_resize = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX) wx.Frame.__init__(self, None, title="No Resize", style=no_resize) panel = wx.Panel(self) self.Show() if __name__ == "__main__": app = wx.App(False) frame = NoResizeFrame() app.MainLoop() |
Учтите, что здесь мы используем битвайс операторов, чтобы удалить 3 флажка стилей из wx.DEFAULT_FRAME_STYLE. И, как вы видите, у нас получается рамка, размер которой изменить попросту невозможно.
Создаём рамку без системного меню
Вообще это довольно глупое требование, но я встречал людей, которые просили его выполнить. Проще говоря, нам нужно убрать все кнопки и оставить лишь сам текст заголовка. Вот как это сделать:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import wx class NoSystemMenuFrame(wx.Frame): """ Здесь нет системного меню, а это значит, что строка заголовка всё ещё осталась, но кнопки и меню не отображаются, когда пользователь нажимает в верхний левый угол рамки """ def __init__(self): """Constructor""" no_sys_menu = wx.CAPTION wx.Frame.__init__(self, None, title="No System Menu", style=no_sys_menu) panel = wx.Panel(self) self.Show() if __name__ == "__main__": app = wx.App(False) frame = NoSystemMenuFrame() app.MainLoop() |
Вы заметите, что всё, что мы сделали – это уменьшили количество флажков стиля до одного — wx.CAPTION.
Создаём рамку, которая отображается поверх остальных окон
Очень много программистов спрашивают об этом. Они хотят, чтобы их приложение отображалось поверх всех окон. Учитывая, что нету стопроцентного способа, который будет работать во всех случаях, предлагаю вам довольствовать маленьким кодом, написанным ниже, ведь он почти никогда меня не подводил.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import wx class StayOnTopFrame(wx.Frame): """ Рамка, которая отображается поверх остальных окон """ def __init__(self): """Constructor""" on_top = wx.DEFAULT_FRAME_STYLE | wx.STAY_ON_TOP wx.Frame.__init__(self, None, title="Stay on top", style=on_top) panel = wx.Panel(self) self.Show() if __name__ == "__main__": app = wx.App(False) frame = StayOnTopFrame() app.MainLoop() |
Здесь мы использовали стандартный флажок стиля и добавили (использовали аддон) wx.STAY_ON_TOP.
Примечание: данный пример не работает на Mac OS X El Capitan.
Итоги
Что ж, теперь вы знаете как редактировать почти все стили рамок. Есть ещё несколько других флажков стиля, которые доступны лишь на определённой ОС (вроде wx.ICONIZE) или же просто менее полезны. Для того, чтобы узнать больше о тех флажках, я советую почитать документацию. А пока, продолжайте двигаться вперёд и используйте свои знания по назначению.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»