Книга: Создание настольных Python приложений с графическим интерфейсом пользователя
Назад: Kivy
Дальше: Dear PyGUI

wxPython



Библиотека WxPython – это питон обёртка библиотеки C++ графического интерфейса wxWidgets.

Оригинальная библиотека wxWidgets, написанная на C ++, – это огромная библиотека классов.

И классы графического интерфейса пользователя из этой библиотеки переносятся на Python с помощью модуля wxPython, который пытается максимально точно отразить исходную библиотеку wxWidgets.







Для начала работы с библиотекой WxPython, создадим проект в

PyCharm

и в окне терминала наберем команду pip install -U wxPython для установки библиотеки.







Далее создадим файл питона и наберем простой код.







Здесь мы импортируем модуль wx.

Далее мы определяем объект класса Application.

И создаем окно верхнего уровня как объект класса Frame, заголовок и размер которого задаются в конструкторе.

Frame – это наиболее часто используемое окно верхнего уровня, размер и положение которого может быть изменено пользователем.

Оно имеет строку заголовка и кнопки управления.

И при необходимости можно добавить другие компоненты, такие как строка меню, панель инструментов и строка состояния.

Далее мы помещаем объект Panel в Frame.

И добавляем объект StaticText для отображения «Hello World» внутри окна.

И наконец мы активируем окно фрейма методом show и входим в основной цикл событий объекта Application.







Для создания исполняемого файла приложения, можно воспользоваться инструментом PyInstaller.

Установив который с помощью команды pip, можно набрать команду pyinstaller в терминале и получить исполняемый файл.







Фрейм – это окно, размер и положение которого может быть изменено пользователем.

Это окно имеет границы и строку заголовка и может дополнительно содержать строку меню, панель инструментов и строку состояния.

И фрейм может содержать любое другое окно, кроме фрейма или диалога.

Строку состояния, панель инструментов и меню можно добавить с помощью функций setStatusBar, SetToolBar и SetMenuBar.

В меню есть пункты меню.

Пункты меню – это команды, которые выполняют определенное действие внутри приложения.

И в меню также могут быть подменю, в которых есть свои собственные пункты меню.

Для создания меню используются классы MenuBar, Menu и MenuItem.

Здесь мы добавляем пункт меню в объект меню методом Append.

Первый параметр здесь – это идентификатор пункта меню.

Второй параметр – это название пункта меню.

Третий параметр определяет строку, которая отображается в строке состояния при выборе пункта меню.

Метод Append возвращает созданный пункт меню.

Эта ссылка используется для привязки события.

Здесь мы привязываем пункт меню к методу OnQuit. Этот метод закрывает приложение.

В каждом меню также может быть подменю.

Таким образом, мы можем объединять похожие команды в группы.

В меню мы можем разделять команды разделителем с помощью метода AppendSeparator. Это простая линия.

Также есть три вида пунктов меню. Это обычное меню, это флажок и это радиоэлемент.

Если мы хотим добавить флажок, мы устанавливаем параметр kind как ITEM_CHECK.







Контекстное меню – это список команд, который появляется в некотором контексте.

Например, когда мы щелкаем правой кнопкой мыши на элементе окна, мы видим контекстное меню.

И контекстные меню иногда называют всплывающими меню.

В этом примере мы создаем контекстное меню для главного окна.

В нем два элемента. Пункт меню создается и добавляется к контекстному меню.

И к этому пункту меню может быть привязан обработчик событий.

Если мы щелкнем правой кнопкой мыши на фрейме, мы вызываем метод OnRightDown.

Для этой привязки мы используем событие wx.EVT_RIGHT_DOWN.

В методе OnRightDown мы вызываем метод PopupMenu.

Этот метод показывает контекстное меню.

И контекстные меню появляются в точке наведения курсора мыши.







В меню, которое мы уже рассмотрели, группируются все команды, которые мы можем использовать в приложении.

Панели инструментов обеспечивают быстрый доступ к наиболее часто используемым командам.

Чтобы создать панель инструментов, мы вызываем метод CreateToolBar виджета фрейма.

По умолчанию панель инструментов горизонтальна, не имеет границ и отображает значки.

Чтобы создать элемент панели инструментов, мы вызываем метод AddTool.

Первый параметр, это идентификатор элемента.

Второй параметр – это метка элемента, третий – изображение элемента.

И обратите внимание, что метка не отображается, потому что стиль по умолчанию показывает только значки.

Также мы можем добавить группу RadioTool, из которой можно выбрать только один элемент.

После того, как мы разместили наши элементы на панели инструментов, мы вызываем метод Realize.

Кнопки инструментов генерируют событие EVT_TOOL, с помощью которого мы можем привязать обработчик элемента панели инструментов.







Теперь, давайте поговорим о компоновках в wxPython, с помощью которых виджеты размещаются внутри виджетов-контейнеров.

В wxPython можно размещать виджеты, используя абсолютное позиционирование или используя сайзеры.

При абсолютном позиционировании мы указываем положение и размер каждого виджета в пикселях.

И абсолютное позиционирование имеет ряд недостатков, а именно – размер и положение виджета не меняются, если мы изменяем размер окна, также приложения выглядят по-разному на разных платформах и изменение шрифтов в приложении может испортить компоновку.

Поэтому чаще всего в реальных программах используются сайзеры.

Здесь в этом примере мы размещаем три метки методом SetPosition используя абсолютное позиционирование.







Сайзеры решают все проблемы абсолютного позиционирования, и wxPython имеет сайзеры

BoxSizer

,

StaticBoxSizer

,

GridSizer

,

FlexGridSizer

,

GridBagSizer

, и

BoxSizer

.

Компоновка BoxSizer позволяет размещать несколько виджетов в строке или столбце.

И мы можем добавлять один сайзер в другой. Таким образом мы можем создавать очень сложные макеты.

Ориентация компоновки может быть вертикальная или горизонтальная.

И добавление виджетов в BoxSizer осуществляется с помощью метода Add.

Параметр пропорции определяет соотношение изменения виджетов в заданной ориентации.

Предположим, у нас есть три элемента с пропорциями 0, 1 и 2.

И они добавлены в горизонтальный BoxSizer.

Элемент с пропорцией 0 вообще не изменится.

Элемент с пропорцией 2 изменится в два раза больше, чем элемент с пропорцией 1 по горизонтали.

С помощью параметра flag вы можете дополнительно настроить поведение виджетов в BoxSizer.

Здесь мы можем контролировать границу border между виджетами, добавляя промежуток между виджетами в пикселях.

Чтобы применить границу, нам нужно определить стороны, где будет использоваться граница.

И мы можем комбинировать стороны, например LEFT | BOTTOM.

И наконец сайзер задается для контейнера с помощью метода setSizer.







Компоновка GridSizer размещает виджеты в двухмерной таблице.

И каждая ячейка в этой таблице имеет одинаковый размер.

Здесь в конструкторе мы указываем количество строк и столбцов в таблице, а также вертикальное и горизонтальное расстояние между ячейками.

Здесь мы использовали метод Add. И виджеты размещаются внутри таблицы в том порядке, в котором они добавляются. Сначала заполняется первая строка, затем вторая строка и т. д.

В методе Add мы используем параметры flag и border, которые определяют ширину границы ячейки.







Компоновка

FlexGridSizer

похожа на

GridSizer

.

Она также размещает свои виджеты в двухмерной таблице.

Но в то время как ячейки GridSizer имеют одинаковый размер, в FlexGridSizer строки и столбцы не обязательно имеют одинаковую высоту или ширину.

Поэтому эта компоновка обеспечивает немного больше гибкости при размещении элементов в ячейках.

Здесь размер каждой ячейки не одинаков, как в GridSizer.

И ширина и высота ячеек в одном столбце или строке может быть увеличена с помощью методов AddGrowableRow и AddGrowableCol.

Первый параметр здесь индекс строки или индекс столбца, а второй параметр – это доля прироста.







Компоновка GridBagSizer – это самая гибкая компоновка в wxPython.

Эта компоновка позволяет явно позиционировать элементы.

Элементы также могут занимать более одной строки или столбца.

И мы добавляем элементы с помощью метода Add.

Здесь параметр pos указывает положение в сетке.

В верхней левой ячейке pos (0, 0).

Параметр span – это диапазон элемента, например span (3, 2) – это виджет занимает 3 строки и 2 столбца.

Параметры флаг и граница обсуждались в BoxSizer.

И ширина и высота ячеек в одном столбце или строке может быть увеличена с помощью методов AddGrowableRow и AddGrowableCol.

Таким образом, GridBagSizer – это универсальная компоновка.

Здесь дочерний виджет можно добавить в определенную ячейку сетки.

Кроме того, дочерний виджет может занимать более одной ячейки по горизонтали или вертикали.







Диалоговые окна являются неотъемлемой частью большинства приложений с графическим интерфейсом.

Диалог используется для ввода данных, изменения данных, изменения настроек приложения и т. д.

И мы можем использовать предопределенные диалоги, такие как окна сообщений, диалоги шрифтов или цветов, или создавать свои собственные диалоги.

Окно сообщения предоставляет пользователю краткую информацию.

И класс MessageBox показывает небольшое диалоговое окно.

Здесь мы предоставляем три параметра: текстовое сообщение, заголовок сообщения и флаги. Флаги используются для отображения различных кнопок и значков.

В нашем случае мы показываем кнопку ОК и значок информации.

Создать диалоговое окно сообщения просто.

Мы устанавливаем диалог как окно верхнего уровня, указав None в качестве родителя.

Чтобы отобразить диалог на экране, мы вызываем метод ShowModal.

Чтобы создать диалоговое окно about, мы должны создать два объекта – wx.adv.AboutDialogInfo и wx.adv.AboutBox.

Для создания собственного диалога, мы должны создать класс, который наследует от виджета wx.Dialog.

Мы создаем экземпляр этого класса, а затем мы вызываем метод ShowModal.

Позже мы должны уничтожить наш диалог с помощью метода Destroy.







Теперь давайте пройдемся по виджетам библиотеки wxPython.

Button – это простой виджет, который содержит текстовую строку и используется для запуска действия.

В этом примере мы создаем кнопку «Закрыть», которая при нажатии завершает работу приложения.

В конструкторе виджета мы указываем метку для кнопки и позицию на панели.

Методом Bind мы связываем событие с методом, и событие запускается, когда мы нажимаем на кнопку.

Здесь мы указываем обработчик для этого события, в котором мы завершаем приложение с помощью метода Close.







Виджет ToggleButton – это кнопка, которая имеет два состояния: нажата и не нажата.

И вы переключаетесь между этими двумя состояниями, нажимая на кнопку.

В этом примере мы меняем цвет панели, нажимая на кнопку.

Здесь создается виджет ToggleButton и панель, цвет которой мы будем изменять с помощью кнопки-переключателя.

Обработчик события Toggle вызывается, когда мы нажимаем кнопку.

В этом методе мы устанавливаем цвет фона панели в зависимости от того нажата кнопка или нет.







Виджет StaticText отображает одну или несколько строк текста, доступного только для чтения.

Здесь мы создаем шрифт для текста.

И устанавливаем шрифт с помощью метода SetFont.

Виджет StaticLine отображает в окне простую строку, которая может использоваться как разделительная строка.







Виджет StaticBox используется для логической группировки различных виджетов.

И эти виджеты должны быть родственными, а не дочерними по отношению к статическому блоку.

Здесь включаемые виджеты регулируются размерами рамки статического блока.

Какая будет рамка, столько виджетов и поместится в блок.

Виджет ComboBox – это выпадающий список с кнопкой.

Когда вы нажимаете кнопку, появляется список.

И пользователь может выбрать только один вариант из предоставленного списка строк.

При создании виджета ComboBox, параметр choices принимает список строк, отображаемых в поле со списком.

Стиль READONLY делает строки списка доступными только для чтения.

И когда мы выбираем параметр из поля со списком, запускается событие COMBOBOX.

К этому событию мы подключаем обработчик события OnSelect.







CheckBox – это виджет, который имеет два состояния: включен и выключен.

Здесь мы проверяем состояние виджета CheckBox с помощью метода GetValue.

И событие CHECKBOX запускается, когда мы щелкаем по виджету CheckBox.

При запуске этого события вызывается обработчик ShowOrHide.







RadioButton – это виджет, который позволяет пользователю выбрать один вариант из группы параметров.

Группа переключателей определяется тем, что первый переключатель в группе содержит стиль GROUP.

Все остальные переключатели, определенные после первого переключателя с этим флагом стиля, будут добавлены в функциональную группу первого переключателя.

Объявление другой радиокнопки с флагом GROUP запустит новую группу радиокнопок.

Здесь у нас есть группа из двух переключателей.

И состояние каждого из переключателей отображается в строке состояния.

И мы привязываем событие RADIOBUTTON к обработчику события SetVal.

Также мы создаем статусбар с двумя полями.

В методе SetVal мы узнаем состояния переключателей.

И мы обновляем поля строки состояния до текущих значений переключателей.







Датчик Gauge – это виджет, который используется при выполнении длительных задач, где требуется индикатор, показывающий текущее состояние задачи.

В этом примере у нас есть датчик и кнопка, которая запускает датчик.

И мы используем Timer для выполнения кода через определенные промежутки времени.

В эти моменты мы обновляем шкалу датчика.

Переменная count используется для определения того, какая часть задачи уже выполнена.

В конструкторе виджета Gauge, параметр диапазона устанавливает максимальное целочисленное значение виджета.

Когда мы нажимаем кнопку ОК, вызывается метод OnStart.

Здесь сначала мы проверяем, находится ли переменная count в диапазоне задачи.

Если нет, то возвращаемся из метода.

Если же задача еще не выполнена, мы запускаем таймер.

И метод OnTimer вызывается периодически после запуска таймера.

В этом методе мы обновляем переменную count и виджет датчика.

Если переменная count равна максимальному значению, мы останавливаем таймер.







Slider – это виджет с ползунком, который можно тянуть вперед и назад.

Таким образом, мы можем выбрать конкретное значение из диапазона.

Здесь, значение, выбранное в ползунке, отображается в строке статуса.

При создании Slider, мы указываем начальную позицию ползунка параметром value, а минимальное и максимальное положение ползунка – параметрами minValue и maxValue.

Стиль HORIZONTAL делает ползунок горизонтальным.

Когда появляется событие SCROLL, здесь вызывается метод OnSliderScroll, в котором текущее выбранное значение ползунка отображается в строке статуса.







Виджет SpinCtrl позволяет увеличивать и уменьшать значение в определенном диапазоне.

Здесь мы переводим температуру по Фаренгейту в градусы Цельсия.

Мы создаем виджет SpinCtrl с начальным значением 0.

И метод SetRange устанавливает диапазон значений для виджета.

Когда мы выбираем значение в виджете, вызывается метод OnCompute.

В этом методе мы получаем текущее значение и вычисляем температуру по Цельсию и показываем вычисленную температуру в строке статуса.







Виджет ListBox представляет собой список строк с вертикальной прокруткой.

И по умолчанию можно выбрать один элемент в списке. Однако список можно настроить и для множественного выбора.

Здесь параметр Choices – это список строк, используемых для заполнения списка.

В этом примере ListBox заполняется строками с помощью объекта languages.

И ListBox связывается с обработчиком onListBox с помощью события LISTBOX.

Этот обработчик добавляет выбранную строку в многострочный виджет TextCtrl.







Теперь, как создать не список, а таблицу?

ListCtrl – это улучшенный виджет списка.

Если ListBox показывает только один столбец, ListCtrl может содержать несколько столбцов.

Внешний вид виджета ListCtrl контролируется параметрами стиля.

Столбцы заголовка создаются методом InsertColumn, который принимает параметры номера столбца, заголовок, стиль и ширину.

Здесь список кортежей, каждый из которых содержит три строки, хранит данные, которые используются для заполнения столбцов объекта ListCtrl.

Новая строка заполняется методом InsertStringItem, который возвращает индекс текущей строки.

Использование maxint дает номер строки после последней строки.

Используя индекс, другие столбцы заполняются методом SetStringItem.

Событие LIST_ITEM_SELECTED передает индекс выбранного элемента из таблицы.

И мы используем этот индекс в обработчике, чтобы получить элемент и столбец в таблице, чтобы получить текст ячейки.







Библиотека wxHTML и iewin содержат классы для анализа и отображения содержимого HTML.

Хотя этот браузер не предназначен для использования в качестве полнофункционального браузера, объект IEHtmlWindow может служить универсальным средством просмотра HTML.

Хотя для использования этого браузера понадобится установка дополнительного модуля comtypes, питон COM-пакета.







SplitterWindow – это специальная компоновка, которая содержит два подокна, размер которых можно динамически изменять, перетаскивая границы между ними.

Класс SplitterWindow имеет очень простой конструктор с параметрами, имеющими значения по умолчанию.

В этом примере SplitterWindow добавляется к фрейму верхнего уровня.

Одна панель предназначена для хранения многострочного поля TextCtrl.

Список ListBox помещается на другую панель.

И SplitterWindow разделяет по вертикали окно, и две панели добавляются в подокна.

Ширину подокон можно изменять с помощью перетаскивания границы.







Библиотека wxPython содержит набор виджетов Book, которые позволяют пользователю переключаться между различными панелями в окне.

Это такие виджеты как Notebook, Choicebook, Listbook и Treebook.

Виджет Notebook представляет собой окно с вкладками или страницами.

И пользователь может переключаться между страницами, щелкая заголовок соответствующей вкладки.

Объекты этих вкладок добавляются как страницы в Notebook во фрейме верхнего уровня.







API рисования wxPython предлагает различные функции для рисования форм, текста и изображений.

Объекты, необходимые для рисования, такие как цвет, перо, кисть и шрифт, могут быть созданы с использованием классов интерфейса.

Класс PaintDC используется для рисования в клиентской области окна, с помощью события PaintEvent.

Существуют также такие классы как ScreenDC, который используется для рисования на экране, и ClientDC, который используется для рисования в клиентской области окна без события PaintEvent.

Класс Colour представляет собой комбинацию значений RGB и есть также предопределенные цветовые объекты, такие как BLACK, BLUE, GREEN и так далее.

Цвет с произвольной комбинацией значений RGB формируется как объект Colour.

Объект Pen определяет цвет, ширину и стиль форм, таких как линия, прямоугольник, круг и т. д.

Кисть Brush – это еще один графический объект, необходимый для заливки фона таких фигур, как прямоугольник, эллипс, круг и т. д.

Для настраиваемого объекта Brush требуются параметры стиля Colour и Brush.

Здесь пример показывает использование объектов Pen, Brush, Color и Font.

Назад: Kivy
Дальше: Dear PyGUI