wxPython - Краткое руководство
wxPython это оболочка Python для wxWidgets(который написан на C ++), популярный кроссплатформенный инструментарий GUI. Разработанный Робином Данном вместе с Харри Пасаненом, wxPython реализован как модуль расширения Python.
Как и wxWidgets, wxPython также является бесплатным программным обеспечением. Его можно скачать с официального сайтаhttp://wxpython.org. Бинарные файлы и исходный код для многих платформ операционных систем доступны для загрузки на этом сайте.
Основные модули в wxPython API включают основной модуль. Это состоит изwxObjectclass, который является базовым для всех классов в API. Модуль управления содержит все виджеты, используемые при разработке приложений с графическим интерфейсом. Например, wx.Button, wx.StaticText (аналог метки), wx.TextCtrl (элемент управления редактируемым текстом) и т. Д.
wxPython API имеет модуль GDI (интерфейс графического устройства). Это набор классов, используемых для рисования на виджетах. В него входят такие классы, как шрифт, цвет, кисть и т. Д. Все классы окон контейнера определены в модуле Windows.
На официальном сайте wxPython также находится Project Phoenix - новая реализация wxPython для Python 3. *. Он ориентирован на повышение скорости, ремонтопригодности и расширяемости. Проект стартовал в 2012 году и все еще находится в стадии бета-тестирования.
Windows
Готовые двоичные файлы для ОС Windows (32- и 64-разрядные версии) доступны на http://www.wxpython.org/download.phpстраница. Доступны последние версии установщиков - wxPython3.0-win32-3.0.2.0-py27.exe для 32-битного Python 2.7 wxPython3.0-win64-3.0.2.0-py27.exe для 64-битного Python 2.7
Демо wxPython, примеры и документация по wxWidgets также доступны для загрузки на той же странице.
wxPython3.0-win32-docs-demos.exe
Linux
Бинарные файлы wxPython для многих дистрибутивов Linux можно найти в соответствующих репозиториях. Для загрузки и установки необходимо будет использовать соответствующие менеджеры пакетов. Например, в Debian Linux следующая команда должна иметь возможность установить wxPython.
sudo apt-get install python-wxgtk3.0
MacOS
Готовые двоичные файлы для MacOS в виде образов дисков доступны на странице загрузки официального сайта.
Простое приложение с графическим интерфейсом пользователя, отображающее сообщение Hello World, создается с использованием следующих шагов:
Импортировать модуль wx.
Определите объект класса Application.
Создайте окно верхнего уровня как объект класса wx.Frame. Параметры заголовка и размера задаются в конструкторе.
Хотя в объект Frame можно добавить другие элементы управления, их макетом нельзя управлять. Следовательно, поместите объект Panel в Frame.
Добавьте объект StaticText для отображения Hello World в желаемой позиции внутри окна.
Активируйте окно фрейма методом show ().
Войдите в основной цикл событий объекта Application.
import wx
app = wx.App()
window = wx.Frame(None, title = "wxPython Frame", size = (300,200))
panel = wx.Panel(window)
label = wx.StaticText(panel, label = "Hello World", pos = (100,50))
window.Show(True)
app.MainLoop()
Приведенный выше код дает следующий вывод -
wxFrame objectявляется наиболее часто используемым окном верхнего уровня. Это получено изwxWindow class. Фрейм - это окно, размер и положение которого может быть изменено пользователем. Он имеет строку заголовка и кнопки управления. При необходимости можно включить другие компоненты, такие как строка меню, панель инструментов и строка состояния. Окно wxFrame может содержать любой фрейм, кроме диалога или другого фрейма.
Создание красивого графического интерфейса с помощью ручного кодирования может быть утомительным. Инструмент визуального графического интерфейса пользователя всегда под рукой. Доступно множество IDE для разработки графического интерфейса, ориентированных на wxPython. Ниже приведены некоторые из них -
- wxFormBuilder
- wxDesigner
- wxGlade
- BoaConstructor
- gui2py
wxFormBuilder- это кроссплатформенный конструктор графического интерфейса пользователя WYSIWYG с открытым исходным кодом, который может переводить дизайн графического интерфейса пользователя wxWidget в формат C ++, Python, PHP или XML. Здесь дается краткое введение в использование wxFormBuilder.
Прежде всего, необходимо загрузить и установить последнюю версию wxFormBuilder из http://sourceforge.net/projects/wxformbuilder/. При открытии приложения появляется новый проект с пустой серой областью в центре.
Дайте проекту подходящее имя и выберите Python в качестве языка генерации кода. Это делается в окне свойств объекта, как показано на следующем изображении -
Затем на вкладке «Формы» палитры компонентов выберите «Рамка».
Добавьте вертикальный wxBoxSizer из вкладки «Макеты».
Добавьте необходимые элементы управления в поле с подходящими подписями. Здесь добавляются StaticText (метка), два объекта TextCtrl (текстовые поля) и объект wxButton. Рамка выглядит как на следующем изображении -
Включите Expand и Stretch для этих трех элементов управления. В свойствах объекта wxButton назначьте функцию findquare () событию OnButtonClick.
Сохраните проект и нажмите F8, чтобы сгенерировать код Python для разработанного графического интерфейса. Пусть сгенерированный файл будет называться Demo.py
В исполняемом скрипте Python импортируйте demo.py и определите функцию FindSquare (). Объявите объект Application и запустите цикл основного события. Ниже приведен исполняемый код -
import wx
#import the newly created GUI file
import demo
class CalcFrame(demo.MyFrame1):
def __init__(self,parent):
demo.MyFrame1.__init__(self,parent)
def FindSquare(self,event):
num = int(self.m_textCtrl1.GetValue())
self.m_textCtrl2.SetValue (str(num*num))
app = wx.App(False)
frame = CalcFrame(None)
frame.Show(True)
#start the applications
app.MainLoop()
Приведенный выше код дает следующий вывод -
Оригинальные wxWidgets (написанные на C ++) - огромная библиотека классов. Классы GUI из этой библиотеки переносятся на Python с помощью модуля wxPython, который пытается максимально точно отразить исходную библиотеку wxWidgets. Итак, класс wx.Frame в wxPython действует примерно так же, как класс wxFrame в своей версии C ++.
wxObject является базой для большинства классов. Объект wxApp (wx.App в wxPython) представляет само приложение. После создания графического интерфейса приложение входит в цикл событий с помощью метода MainLoop (). На следующих диаграммах изображена иерархия классов наиболее часто используемых классов GUI, включенных в wxPython.
SN | Классы и описание |
---|---|
1 | wx.Frame Класс wx.Frame имеет конструктор по умолчанию без аргументов. |
2 | wx.Panel Класс wx.Panel обычно помещается в объект wxFrame. Этот класс также унаследован от класса wxWindow. |
3 | wx.StaticText Объект класса wx.StaticText представляет собой элемент управления, содержащий такой текст только для чтения. Его можно назвать пассивным контролем, поскольку он не производит никаких событий. |
4 | TextCtrl В wxPython для этой цели служит объект класса wx.TextCtrl. Это элемент управления, в котором можно отображать и редактировать текст. |
5 | RadioButton и RadioBox Каждая кнопка, объект класса wx.RadioButton, несет текстовую метку рядом с круглой кнопкой. API wxPython также состоит из класса wx.RadioBox. Его объект предлагает границу и метку для группы. |
6 | wx.CheckBox Флажок отображает небольшое прямоугольное поле с надписью. При нажатии внутри прямоугольника появляется галочка, указывающая на то, что выбор сделан. |
7 | ComboBox и класс выбора Объект wx.ComboBox представляет собой список элементов для выбора. Его можно настроить в виде раскрывающегося списка или с постоянным отображением. API wxPython содержит класс wx.Choice, объект которого также является раскрывающимся списком, который постоянно доступен только для чтения. |
8 | Wx.Gauge Объект класса Wx.Gauge показывает вертикальную или горизонтальную полосу, которая графически показывает увеличивающееся количество. |
9 | wx.Slider API wxPython содержит класс wx.Slider. Он предлагает те же функции, что и полоса прокрутки. Slider предлагает удобный способ обработки перетаскивания маркера привязкой событий wx.EVT_SLIDER для конкретного слайдера. |
10 | wx.MenuBar Горизонтальная полоса чуть ниже строки заголовка окна верхнего уровня зарезервирована для отображения ряда меню. Это объект класса wx.MenuBar в API wxPython. |
11 | wx.Toolbar Если для параметра стиля объекта wx.Toolbar установлено значение wx.TB_DOCKABLE, он становится прикрепляемым. Плавающую панель инструментов также можно создать с помощью класса AUIToolBar из wxPython. |
12 | Wx.Dialog Хотя объект класса Dialog выглядит как фрейм, он обычно используется как всплывающее окно поверх родительского фрейма. Цель диалога - собрать некоторые данные от пользователя и отправить их в родительский фрейм. |
13 | wx.Ноутбук Виджет wx.Notebook представляет собой элемент управления с вкладками. Один объект Notebook во фрейме имеет одну или несколько вкладок (называемых страницами), каждая из которых имеет панель, отображающую расположение элементов управления. |
14 | wx.SplitterWindow Объект этого класса - диспетчер компоновки, содержащий два подокна, размер которых можно динамически изменять, перетаскивая границы между ними. Элемент управления Splitter предоставляет дескриптор, который можно перетаскивать для изменения размера элементов управления. |
15 | HTMLWindow Библиотека wxHTML содержит классы для анализа и отображения содержимого HTML. Хотя этот браузер не предназначен для использования в качестве полнофункционального браузера, объект wx.HtmlWindow представляет собой обычную программу просмотра HTML. |
16 | ListBox и ListCtrl Виджет wx.ListBox представляет собой список строк с вертикальной прокруткой. По умолчанию можно выбрать один элемент в списке. Виджет ListCtrl - это усовершенствованный инструмент для отображения и выбора списка. Список из более чем одного столбца может отображаться в представлении «Отчет», «Список» или «Значок». |
В отличие от приложения консольного режима, которое выполняется последовательно, приложение на основе графического интерфейса пользователя управляется событиями. Функции или методы выполняются в ответ на действия пользователя, такие как нажатие кнопки, выбор элемента из коллекции или щелчок мышью и т. Д., Называемые событиями.
Данные, относящиеся к событию, которое происходит во время выполнения приложения, хранятся как объект подкласса, производного от wx.Event. Элемент управления отображением (например, Button) является источником события определенного типа и создает связанный с ним объект класса Event. Например, нажатие кнопки вызывает событие wx.CommandEvent. Эти данные о событии отправляются методу обработчика событий в программе. wxPython имеет множество предопределенных связывателей событий. AnEvent binder инкапсулирует отношения между конкретным виджетом (элементом управления), связанным с ним типом события и методом обработчика событий.
Например, позвонить OnClick() method программы в событии нажатия кнопки требуется следующий оператор -
self.b1.Bind(EVT_BUTTON, OnClick)
Bind() methodнаследуется всеми экранными объектами из класса wx.EvtHandler. EVT_.BUTTON - это связка, которая связывает событие нажатия кнопки с методом OnClick ().
пример
В следующем примере MoveEvent, вызванное перетаскиванием окна верхнего уровня - в данном случае объекта wx.Frame - подключается к OnMove() methodиспользуя связыватель wx.EVT_MOVE. Код отображает окно. Если его перемещать с помощью мыши, его мгновенные координаты отображаются на консоли.
import wx
class Example(wx.Frame):
def __init__(self, *args, **kw):
super(Example, self).__init__(*args, **kw)
self.InitUI()
def InitUI(self):
self.Bind(wx.EVT_MOVE, self.OnMove)
self.SetSize((250, 180))
self.SetTitle('Move event')
self.Centre()
self.Show(True)
def OnMove(self, e):
x, y = e.GetPosition()
print "current window position x = ",x," y= ",y
ex = wx.App()
Example(None)
ex.MainLoop()
Приведенный выше код дает следующий вывод -
текущая позиция окна x = 562 y = 309
текущая позиция окна x = 562 y = 309
текущая позиция окна x = 326 y = 304
текущая позиция окна x = 384 y = 240
текущая позиция окна x = 173 y = 408
текущая позиция окна x = 226 y = 30
текущая позиция окна x = 481 y = 80
Некоторые из подклассов, унаследованных от wx.Event, перечислены в следующей таблице -
SN | События и описание |
---|---|
1 | wxKeyEvent Происходит при нажатии или отпускании клавиши |
2 | wxPaintEvent Генерируется всякий раз, когда необходимо перерисовать содержимое окна |
3 | wxMouseEvent Содержит данные о любом событии из-за активности мыши, например, нажатия или перетаскивания кнопки мыши |
4 | wxScrollEvent Связан с прокручиваемыми элементами управления, такими как wxScrollbar и wxSlider |
5 | wxCommandEvent Содержит данные о событиях, происходящие из многих виджетов, таких как кнопка, диалоги, буфер обмена и т. Д. |
6 | wxMenuEvent Различные события, связанные с меню, за исключением нажатия кнопки меню |
7 | wxColourPickerEvent wxColourPickerCtrl сгенерированные события |
8 | wxDirFilePickerEvent События, генерируемые FileDialog и DirDialog |
События в wxPython бывают двух типов. Основные события и командные события. Базовое событие остается локальным для окна, в котором оно возникает. Большинство wxWidgets генерируют командные события. Аcommand event может распространяться на окно или окна, которые находятся выше исходного окна в иерархии классов.
пример
Ниже приводится простой пример распространения событий. Полный код -
import wx
class MyPanel(wx.Panel):
def __init__(self, parent):
super(MyPanel, self).__init__(parent)
b = wx.Button(self, label = 'Btn', pos = (100,100))
b.Bind(wx.EVT_BUTTON, self.btnclk)
self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
def OnButtonClicked(self, e):
print 'Panel received click event. propagated to Frame class'
e.Skip()
def btnclk(self,e):
print "Button received click event. propagated to Panel class"
e.Skip()
class Example(wx.Frame):
def __init__(self,parent):
super(Example, self).__init__(parent)
self.InitUI()
def InitUI(self):
mpnl = MyPanel(self)
self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
self.SetTitle('Event propagation demo')
self.Centre()
self.Show(True)
def OnButtonClicked(self, e):
print 'click event received by frame class'
e.Skip()
ex = wx.App()
Example(None)
ex.MainLoop()
В приведенном выше коде есть два класса. MyPanel, подкласс wx.Panel и Example, подкласс wx.Frame, который является окном верхнего уровня для программы. На панели находится кнопка.
Этот объект Button привязан к обработчику события btnclk (), который передает его родительскому классу (в данном случае MyPanel). Нажатие кнопки вызываетCommandEvent который может быть передан своему родительскому объекту методом Skip ().
Объект класса MyPanel также связывает полученное событие с другим обработчиком OnButtonClicked (). Эта функция, в свою очередь, передает своему родительскому классу Example. Приведенный выше код дает следующий вывод -
Button received click event. Propagated to Panel class.
Panel received click event. Propagated to Frame class.
Click event received by frame class.
Виджет с графическим интерфейсом пользователя можно разместить внутри окна контейнера, указав его абсолютные координаты в пикселях. Координаты относятся к размерам окна, определенным аргументом size его конструктора. Положение виджета внутри окна определяетсяpos аргумент его конструктора.
import wx
app = wx.App()
window = wx.Frame(None, title = "wxPython Frame", size = (300,200))
panel = wx.Panel(window)
label = wx.StaticText(panel, label = "Hello World", pos = (100,50))
window.Show(True)
app.MainLoop()
Этот Absolute Positioning однако не подходит по следующим причинам -
Положение виджета не меняется даже при изменении размера окна.
Внешний вид может быть неодинаковым на разных устройствах отображения с разным разрешением.
Изменить макет сложно, так как может потребоваться переработка всей формы.
API wxPython предоставляет классы макета для более элегантного управления размещением виджетов внутри контейнера. Преимущества менеджеров компоновки перед абсолютным позиционированием:
- Размер виджетов внутри окна изменяется автоматически.
- Обеспечивает единообразный внешний вид на устройствах отображения с разным разрешением.
- Динамическое добавление или удаление виджетов возможно без изменения дизайна.
В wxPython менеджер компоновки называется Sizer. Wx.Sizer - это базовый класс для всех подклассов сайзера. Давайте обсудим некоторые важные сайзеры, такие как wx.BoxSizer, wx.StaticBoxSizer, wx.GridSizer, wx.FlexGridSizer и wx.GridBagSizer.
SN | Размеры и описание |
---|---|
1 | BoxSizer Этот классификатор позволяет расположить элементы управления по строкам или по столбцам. Макет BoxSizer определяется его аргументом ориентации (wxVERTICAL или wxHORIZONTAL). |
2 | GridSizer Как следует из названия, объект GridSizer представляет собой двумерную сетку. Элементы управления добавляются в слот сетки в порядке слева направо и сверху вниз. |
3 | FlexiGridSizer Этот классификатор также имеет двумерную сетку. Однако он обеспечивает немного больше гибкости при размещении элементов управления в ячейках. |
4 | GridBagSizer GridBagSizer - универсальный классификатор. Он предлагает больше улучшений, чем FlexiGridSizer. Дочерний виджет можно добавить в определенную ячейку в сетке. |
5 | StaticBoxSizer StaticBoxSizer помещает размер окна в статический блок. Он обеспечивает границу вокруг поля вместе с меткой вверху. |
Виджет-кнопка наиболее широко используется в любом графическом интерфейсе пользователя. Он фиксирует событие щелчка, созданное пользователем. Его наиболее очевидное использование - запускать связанную с ним функцию-обработчик.
Библиотека классов wxPython предоставляет различные типы кнопок. Есть простая традиционная кнопка,wx.Buttonобъект класса, который содержит текст в качестве заголовка. Также доступна кнопка с двумя состояниями, которая называетсяwx.ToggleButton. Его нажатое или подавленное состояние может быть идентифицировано функцией обработчика событий.
Другой тип кнопки, wx.BitmapButton отображает растровое изображение (изображение) в виде значка на лицевой стороне.
Конструктор для классов wx.Button и wx.ToggleButton принимает следующие аргументы:
Wx.Button(parent, id, label, pos, size, style)
Это некоторые важные методы класса wx.Button -
SN | Методы и описание |
---|---|
1 | SetLabel() Программно устанавливает заголовок кнопки |
2 | GetLabel() Возвращает подпись кнопки |
3 | SetDefault() Кнопка установлена по умолчанию для окна верхнего уровня. Эмулирует событие щелчка при нажатии клавиши Enter |
Два важных метода класса wx.ToggleButton:
SN | Методы и описание |
---|---|
1 | GetValue() Возвращает состояние кнопки переключения (вкл / выкл) |
2 | SetValue() Программно устанавливает состояние кнопки |
Чтобы создать кнопку растрового изображения, во-первых, объект растрового изображения должен быть сконструирован из файла изображения.
Чаще всего используется следующий вариант конструктора класса wx.Bitmap:
Wx.Bitmap(fiiename, wx.BITMAP_TYPE)
Некоторые из предопределенных констант типа растрового изображения:
wx.BITMAP_TYPE_BMP |
wx.BITMAP_TYPE_ICO |
wx.BITMAP_TYPE_CUR |
wx.BITMAP_TYPE_TIFF |
wx.BITMAP_TYPE_TIF |
wx.BITMAP_TYPE_GIF |
wx.BITMAP_TYPE_PNG |
wx.BITMAP_TYPE_JPEG |
wx.BITMAP_TYPE_PCX |
wx.BITMAP_TYPE_ICON |
wx.BITMAP_TYPE_ANY |
Этот растровый объект используется как один из параметров конструктора класса wx.BitmapButton.
Wx.BitmapButton(parent, id, bitmap, pos, size, style)
На некоторых платформах ОС кнопка растрового изображения может отображать как растровое изображение, так и метку. Методы SetLabel () назначают заголовок. На других платформах он служит внутренней меткой.
Обычная кнопка, а также кнопка растрового изображения излучает событие wx.CommandEvent. Связывание EVT_BUTTON связывает с ним функцию-обработчик.
С другой стороны, кнопка переключения использует связыватель wx.TOGGLEBUTTON для обработки событий.
В следующем примере кнопки всех трех типов помещаются в вертикальный размер окна панели.
Простой объект кнопки создается с помощью оператора -
self.btn = wx.Button(panel, -1, "click Me")
Кнопка переключения создается следующим утверждением -
self.tbtn = wx.ToggleButton(panel , -1, "click to on")
Эти кнопки добавляются в вертикальный размер с помощью следующих операторов:
vbox.Add(self.btn,0,wx.ALIGN_CENTER)
vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER)
Note - Из-за флага wx.EXPAND кнопка-переключатель занимает всю ширину кадра.
Используя связыватели EVT_BUTTON и EVT_TOGGLEBUTTON, они связываются с соответствующими обработчиками.
self.btn.Bind(wx.EVT_BUTTON,self.OnClicked)
self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle)
Три кнопки растровых изображений добавлены в горизонтальный размер окна. Эти кнопки отображают изображение в виде значка в качестве заголовка.
bmp = wx.Bitmap("NEW.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
Событие нажатия этих трех кнопок направляется в метод OnClicked ().
self.bmpbtn.Bind(wx.EVT_BUTTON, self.OnClicked)
self.bmpbtn1.Bind(wx.EVT_BUTTON, self.OnClicked)
self.bmpbtn2.Bind(wx.EVT_BUTTON, self.OnClicked)
Внутренние метки этих кнопок установлены на NEW, OPEN и SAVE соответственно.
Функция обработчика событий OnClicked () извлекает метку исходной кнопки, которая вызвала событие щелчка. Эта этикетка напечатана на консоли.
def OnClicked(self, event):
btn = event.GetEventObject().GetLabel()
print "Label of pressed button = ",btn
Обработчик события OnToggle () срабатывает при нажатии кнопки-переключателя. Его состояние считывается методом GetValue () и, соответственно, устанавливается подпись кнопки.
def OnToggle(self,event):
state = event.GetEventObject().GetValue()
if state == True:
print "off"
event.GetEventObject().SetLabel("click to off")
else:
print "on"
event.GetEventObject().SetLabel("click to on")
Полный список кода выглядит следующим образом -
import wx
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title = title,size = (200,150))
panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
self.btn = wx.Button(panel,-1,"click Me")
vbox.Add(self.btn,0,wx.ALIGN_CENTER)
self.btn.Bind(wx.EVT_BUTTON,self.OnClicked)
self.tbtn = wx.ToggleButton(panel , -1, "click to on")
vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER)
self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle)
hbox = wx.BoxSizer(wx.HORIZONTAL)
bmp = wx.Bitmap("NEW.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
hbox.Add(self.bmpbtn,0,wx.ALIGN_CENTER)
self.bmpbtn.Bind(wx.EVT_BUTTON,self.OnClicked)
self.bmpbtn.SetLabel("NEW")
bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
hbox.Add(self.bmpbtn1,0,wx.ALIGN_CENTER)
self.bmpbtn1.Bind(wx.EVT_BUTTON,self.OnClicked)
self.bmpbtn1.SetLabel("OPEN")
bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
hbox.Add(self.bmpbtn2,0,wx.ALIGN_CENTER)
self.bmpbtn2.Bind(wx.EVT_BUTTON,self.OnClicked)
self.bmpbtn2.SetLabel("SAVE")
vbox.Add(hbox,1,wx.ALIGN_CENTER)
panel.SetSizer(vbox)
self.Centre()
self.Show()
self.Fit()
def OnClicked(self, event):
btn = event.GetEventObject().GetLabel()
print "Label of pressed button = ",btn
def OnToggle(self,event):
state = event.GetEventObject().GetValue()
if state == True:
print "Toggle button state off"
event.GetEventObject().SetLabel("click to off")
else:
print " Toggle button state on"
event.GetEventObject().SetLabel("click to on")
app = wx.App()
Mywin(None, 'Button demo')
app.MainLoop()
Приведенный выше код дает следующий вывод -
Ярлык нажатой кнопки = нажмите Me
Отключить состояние кнопки
Включить состояние кнопки
Метка нажатой кнопки = NEW
Ярлык нажатой кнопки = ОТКРЫТЬ
Метка нажатой кнопки = СОХРАНИТЬ
wxAui- это библиотека расширенного пользовательского интерфейса, включенная в wxWidgets API. Wx.aui.AuiManager - центральный класс в структуре AUI.
AuiManagerуправляет панелями, связанными с конкретным фреймом, используя информацию каждой панели в объекте wx.aui.AuiPanelInfo. Давайте узнаем о различных свойствах закрепления и плавающего поведения элемента управления PanelInfo.
Размещение закрепляемых окон в фрейме верхнего уровня включает следующие шаги:
Сначала создайте объект AuiManager.
self.mgr = wx.aui.AuiManager(self)
Затем создается панель с необходимыми элементами управления.
pnl = wx.Panel(self)
pbox = wx.BoxSizer(wx.HORIZONTAL)
text1 = wx.TextCtrl(pnl, -1, "Dockable", style = wx.NO_BORDER | wx.TE_MULTILINE)
pbox.Add(text1, 1, flag = wx.EXPAND)
pnl.SetSizer(pbox)
Устанавливаются следующие параметры AuiPanelInfo.
Direction - Сверху, снизу, слева, справа или по центру
Position- Внутри закрепляемой области можно разместить более одной панели. Каждому дается номер позиции.
Row- В одной строке отображается более одной панели. Точно так же, как несколько панелей инструментов отображаются в одной строке.
Layer - Панели можно размещать слоями.
Используя эту PanelInfo, созданная панель добавляется в объект менеджера.
info1 = wx.aui.AuiPaneInfo().Bottom()
self.mgr.AddPane(pnl,info1)
Остальная часть окна верхнего уровня может иметь другие элементы управления, как обычно.
Полный код выглядит следующим образом -
import wx
import wx.aui
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title = title, size = (300,300))
self.mgr = wx.aui.AuiManager(self)
pnl = wx.Panel(self)
pbox = wx.BoxSizer(wx.HORIZONTAL)
text1 = wx.TextCtrl(pnl, -1, "Dockable", style = wx.NO_BORDER | wx.TE_MULTILINE)
pbox.Add(text1, 1, flag = wx.EXPAND)
pnl.SetSizer(pbox)
info1 = wx.aui.AuiPaneInfo().Bottom()
self.mgr.AddPane(pnl, info1)
panel = wx.Panel(self)
text2 = wx.TextCtrl(panel, size = (300,200), style = wx.NO_BORDER | wx.TE_MULTILINE)
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(text2, 1, flag = wx.EXPAND)
panel.SetSizerAndFit(box)
self.mgr.Update()
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Centre()
self.Show(True)
def OnClose(self, event):
self.mgr.UnInit()
self.Destroy()
app = wx.App()
Mywin(None,"Dock Demo")
app.MainLoop()
Приведенный выше код дает следующий вывод -
Типичное приложение с графическим интерфейсом пользователя может иметь несколько окон. Виджеты с вкладками и стеком позволяют активировать одно такое окно за раз. Однако во многих случаях этот подход может оказаться бесполезным, поскольку вид других окон скрыт.
Один из способов одновременного отображения нескольких окон - создать их как независимые окна. Это называется SDI (Single Document Interface). Это требует больше ресурсов памяти, так как каждое окно может иметь свою собственную систему меню, панель инструментов и т. Д.
Платформа MDI в wxPython предоставляет класс wx.MDIParentFrame. Его объект действует как контейнер для нескольких дочерних окон, каждое из которых является объектом класса wx.MDIChildFrame.
Дочерние окна находятся в области MDIClientWindow родительского фрейма. Как только добавляется дочерний фрейм, в строке меню родительского фрейма отображается меню «Окно», содержащее кнопки для упорядочивания дочерних элементов каскадом или мозаикой.
пример
В следующем примере показано использование MDIParentFrame в качестве окна верхнего уровня. Кнопка меню под названием NewWindow добавляет дочернее окно в клиентскую область. Можно добавить несколько окон, а затем расположить их в каскадном или мозаичном порядке.
Полный код выглядит следующим образом -
import wx
class MDIFrame(wx.MDIParentFrame):
def __init__(self):
wx.MDIParentFrame.__init__(self, None, -1, "MDI Parent", size = (600,400))
menu = wx.Menu()
menu.Append(5000, "&New Window")
menu.Append(5001, "&Exit")
menubar = wx.MenuBar()
menubar.Append(menu, "&File")
self.SetMenuBar(menubar)
self.Bind(wx.EVT_MENU, self.OnNewWindow, id = 5000)
self.Bind(wx.EVT_MENU, self.OnExit, id = 5001)
def OnExit(self, evt):
self.Close(True)
def OnNewWindow(self, evt):
win = wx.MDIChildFrame(self, -1, "Child Window")
win.Show(True)
app = wx.App()
frame = MDIFrame()
frame.Show()
app.MainLoop()
Приведенный выше код дает следующий вывод -
GDI+ (Интерфейс графического рисования), CoreGraphics и Cairo librariesформируют структуру API рисования в wxPython. wx.GraphicsContext - это основной доступный объект, с помощью которого создаются различные объекты контекста устройства.
wx.DC - абстрактный класс. Его производные классы используются для визуализации графики и текста на различных устройствах. Классы контекста устройства:
wx.ScreenDC - Используйте это для рисования на экране, а не в отдельном окне.
wx.ClientDC - Используйте это для рисования в клиентской области окна (части без границ и других украшений), но не используйте это из wxPaintEvent.
wx.PaintDC- Используйте это для рисования в клиентской области окна, но только из wxPaintEvent.
wx.WindowDC- Используйте это, чтобы закрасить всю площадь окна, включая украшения. Это может быть недоступно на платформах, отличных от Windows.
API рисования wxPython предлагает различные функции для рисования формы, текста и изображения. Объекты, необходимые для рисования, такие как цвет, перо, кисть и шрифт, также могут быть созданы с использованием классов GDI.
wx.Colour Класс
Цветовой объект представляет собой комбинацию значений интенсивности RGB (красный, зеленый и синий), каждое по шкале от 0 до 255. Есть несколько предопределенных цветовых объектов, таких как -
- wxBLACK
- wxBLUE
- wxCYAN
- wxGREEN
- wxYELLOW
- wxLIGHT_GREY
- wxRED
- wxWHITE
Цвет с произвольной комбинацией значений RGB формируется как wx.Colour object.
wx.Colour(r,g,b)
Класс wx.Pen
Объект Pen определяет цвет, ширину и стиль формы графики, такой как линия, прямоугольник, круг и т. Д.
Predefined Pen objects являются -
wxBLACK_DASHED_PEN |
wxBLACK_PEN |
wxBLUE_PEN |
wxCYAN_PEN |
wxGREEN_PEN |
wxYELLOW_PEN |
wxGREY_PEN |
wxLIGHT_GREY_PEN |
wxMEDIUM_GREY_PEN |
wxRED_PEN |
wxTRANSPARENT_PEN |
wxWHITE_PEN |
Predefined Pen styles являются -
wx.SOLID |
wx.DOT |
wx.LONG_DASH |
wx.SHORT_DASH |
wx.DOT_DASH |
wx.TRANSPARENT |
wx.Brush Класс
Кисть - это еще один элементарный графический объект, необходимый для заливки фона таких фигур, как прямоугольник, эллипс, круг и т. Д.
Для настраиваемого объекта Brush требуются параметры стиля wx.Colour и Brush. Ниже приведен список предопределенных стилей кисти -
wx.SOLID |
wx.STIPPLE |
wx.BDIAGONAL_HATCH |
wx.CROSSDIAG_HATCH |
wx.FDIAGONAL_HATCH |
wx.CROSS_HATCH |
wx.HORIZONTAL_HATCH |
wx.VERTICAL_HATCH |
wx.TRANSPARENT |
wxPython имеет ряд функций, облегчающих рисование различных форм, текста и изображений.
SN | Функции и описание |
---|---|
1 | DrawRectangle() Рисует прямоугольник заданных размеров |
2 | DrawCircle() Рисует круг в заданной точке как центр и радиус |
3 | DrawEllipse() Рисует эллипс с заданными радиусами x и y |
4 | DrawLine() Рисует линию между двумя объектами wx.Point |
5 | DrawBitmap() Нарисуйте изображение в заданном месте |
6 | DrawText() Отображает данный текст в указанной позиции |
пример
Вышеупомянутые функции реализованы в следующем примере с использованием объектов Pen, Brush, Color и Font.
Полный код выглядит следующим образом -
import wx
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title = title,size = (500,300))
self.InitUI()
def InitUI(self):
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Centre()
self.Show(True)
def OnPaint(self, e):
dc = wx.PaintDC(self)
brush = wx.Brush("white")
dc.SetBackground(brush)
dc.Clear()
dc.DrawBitmap(wx.Bitmap("python.jpg"),10,10,True)
color = wx.Colour(255,0,0)
b = wx.Brush(color)
dc.SetBrush(b)
dc.DrawCircle(300,125,50)
dc.SetBrush(wx.Brush(wx.Colour(255,255,255)))
dc.DrawCircle(300,125,30)
font = wx.Font(18, wx.ROMAN, wx.ITALIC, wx.NORMAL)
dc.SetFont(font)
dc.DrawText("Hello wxPython",200,10)
pen = wx.Pen(wx.Colour(0,0,255))
dc.SetPen(pen)
dc.DrawLine(200,50,350,50)
dc.SetBrush(wx.Brush(wx.Colour(0,255,0), wx.CROSS_HATCH))
dc.DrawRectangle(380, 15, 90, 60)
ex = wx.App()
Mywin(None,'Drawing demo')
ex.MainLoop()
Приведенный выше код дает следующий вывод -
Обеспечение drag and dropочень интуитивно понятен для пользователя. Он присутствует во многих настольных приложениях, где пользователь может копировать или перемещать объекты из одного окна в другое, просто перетаскивая его мышью в другое окно.
Операция перетаскивания включает следующие шаги:
- Объявить цель падения
- Создать объект данных
- Создать wx.DropSource
- Выполнить операцию перетаскивания
- Отменить или принять падение
В wxPython есть две предопределенные цели перетаскивания:
- wx.TextDropTarget
- wx.FileDropTarget
Многие виджеты wxPython поддерживают перетаскивание. В исходном элементе управления должно быть включено перетаскивание, тогда как целевой элемент управления должен быть в состоянии принять (или отклонить) перетаскивание.
Исходные данные, которые перетаскивает пользователь, помещаются в целевой объект. OnDropText () целевого объекта потребляет данные. При желании данные из исходного объекта можно удалить.
пример
В следующем примере два объекта ListCrl размещаются горизонтально в Box Sizer. Список слева заполнен данными языков []. Он обозначен как источник сопротивления. Один справа - цель.
languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript', 'PHP', 'VB.NET','C#']
self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST)
self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST)
for lang in languages:
self.lst1.InsertStringItem(0,lang)
Второй элемент управления списком пуст и является аргументом для объекта класса TextDropTarget.
class MyTextDropTarget(wx.TextDropTarget):
def __init__(self, object):
wx.TextDropTarget.__init__(self)
self.object = object
def OnDropText(self, x, y, data):
self.object.InsertStringItem(0, data)
Метод OnDropText () добавляет исходные данные в целевой элемент управления списком.
Операция перетаскивания инициализируется связывателем событий.
wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)
Функция OnDragInit () помещает данные перетаскивания в цель и удаляет их из источника.
def OnDragInit(self, event):
text = self.lst1.GetItemText(event.GetIndex())
tobj = wx.PyTextDataObject(text)
src = wx.DropSource(self.lst1)
src.SetData(tobj)
src.DoDragDrop(True)
self.lst1.DeleteItem(event.GetIndex())
Полный код выглядит следующим образом -
import wx
class MyTarget(wx.TextDropTarget):
def __init__(self, object):
wx.TextDropTarget.__init__(self)
self.object = object
def OnDropText(self, x, y, data):
self.object.InsertStringItem(0, data)
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title = title,size = (-1,300))
panel = wx.Panel(self)
box = wx.BoxSizer(wx.HORIZONTAL)
languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript',
'PHP', 'VB.NET','C#']
self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST)
self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST)
for lang in languages:
self.lst1.InsertStringItem(0,lang)
dt = MyTarget(self.lst2)
self.lst2.SetDropTarget(dt)
wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)
box.Add(self.lst1,0,wx.EXPAND)
box.Add(self.lst2, 1, wx.EXPAND)
panel.SetSizer(box)
panel.Fit()
self.Centre()
self.Show(True)
def OnDragInit(self, event):
text = self.lst1.GetItemText(event.GetIndex())
tobj = wx.PyTextDataObject(text)
src = wx.DropSource(self.lst1)
src.SetData(tobj)
src.DoDragDrop(True)
self.lst1.DeleteItem(event.GetIndex())
ex = wx.App()
Mywin(None,'Drag&Drop Demo')
ex.MainLoop()
Приведенный выше код дает следующий вывод -