Разное

Python 3 wxpython: 55 УРОКА — Полный курс уроков по wxPython!

Содержание

Установка wxPython на Windows, Mac OS X, Linux

Набор инструментов wxPython GUI не встроен в Python, поэтому вам нужно будет установить его самостоятельно. К счастью, на большинстве платформ сделать это будет достаточно просто. В этой статье мы рассмотрим, как установить wxPython 4.0.3.

Вам нужно просто перейти по ссылке http://www.wxpython.org, найти там подходящий установщик или тарбол, соответствующий вашей платформе и версии Python.

После того как вы установили wxPython, убедитесь, что он выполняет следующий скрипт:

import platform
import wx

class MyFrame(wx.Frame):

def __init__(self):
«»»Constructor»»»
wx.Frame.__init__(
self, None, size=(500, 200), title=’Version Info’
)
panel = wx.Panel(self)

py_version = ‘Python version: ‘ + platform.python_version()
wx_version = ‘wxPython version: ‘ + wx.version()
os_version = ‘Operating System: ‘ + platform.platform()

main_sizer = wx.BoxSizer(wx.VERTICAL)
size = (20, -1)
main_sizer.Add(
wx.StaticText(panel, label=py_version), 0, wx.ALL, 5
)

main_sizer.Add(
wx.StaticText(panel, label=wx_version), 0, wx.ALL, 5
)

main_sizer.Add(
wx.StaticText(panel, label=os_version), 0, wx.ALL, 5
)

panel.SetSizer(main_sizer)

self.Show()

if __name__ == ‘__main__’:
app = wx.App(False)
frame = MyFrame()
app.MainLoop()

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

import platform

import wx

 

class MyFrame(wx.Frame):

 

    def __init__(self):

        «»»Constructor»»»

        wx. Frame.__init__(

            self, None, size=(500, 200), title=’Version Info’

        )

        panel = wx.Panel(self)

 

        py_version = ‘Python version: ‘ + platform.python_version()

        wx_version = ‘wxPython version: ‘ + wx.version()

        os_version = ‘Operating System: ‘ + platform.platform()

 

        main_sizer = wx.BoxSizer(wx.VERTICAL)

        size = (20, -1)

        main_sizer.Add(

            wx.StaticText(panel, label=py_version), 0, wx.ALL, 5

        )

 

        main_sizer.Add(

            wx.StaticText(panel, label=wx_version), 0, wx.ALL, 5

        )

 

        main_sizer.Add(

            wx.StaticText(panel, label=os_version), 0, wx.ALL, 5

        )

 

        panel.SetSizer(main_sizer)

 

        self.Show()

 

 

if __name__ == ‘__main__’:

    app = wx.App(False)

    frame = MyFrame()

    app.MainLoop()

А теперь давайте научимся устанавливать wxPython Classic!

Classic

Ветвь Classic для wxPython была создана путём старомодного вреппинга wxWidgets (например, SWIG вместо SIP). И даже если это не имеет значения для вас как для разработчика, это влияет на процесс установки wxPython. В версии Classic, вы не можете использовать pip для установки wxPython. Вместо этого вам придётся найти установщик, файл deb или dmg, или же, если вы не найдёте подходящего варианта, создать билд wxPython с нуля.

Установка wxPython на Windows

Для пользователей Windows проектом wxPython был предоставлен установщик, который подходит для Classic. Просто зайдите на веб-сайт wxPython и загрузите установщик версии 4.0.3 или новее. Убедитесь в том, что версия установленного у вас Python и платформы совпадают (речь идёт о 32-х и 64-х битных системах).

Пример: вы не сможете установить 64-битную версию wxPython на Python 2.7 для 32-битных систем.

В данном разделе мы рассмотрим процесс установки wxPython на Windows 7. Сразу же после загрузки исполнительного файла, запустите его. Вам нужно будет разрешить установщику доступ к контролю учётных записей пользователей. Это можно сделать, выбрав «Да» в окне, которое всплывёт сразу же после запуска.

Сразу же после этого действия, вы должны увидеть следующий диалог:

Это стандартный мастер установки, с которым вы могли столкнутся в множестве других программ. Нажмите «Далее» и вы будете перенаправлены на окно лицензионного соглашения.

Вы можете прочесть лицензионное соглашение wxPython, если захотите. Оно представляет собой слегка модифицированную версию стандартной лицензии свободного программного обеспечения, позволяющую вам делать с wxPython всё, что вам заблагорассудится, даже продавать собственные коды, написанные с его применением. Просто примите соглашение, чтобы продолжить.

Здесь мы выбираем место, куда будет установлена программа. Установщик достаточно умён, чтобы предложить вам текущее место расположения Python в качестве места установки wxPython. Разумеется, если у вас установлены другие версии Python 2.7, то придётся выбрать путь установки вручную. Когда закончите с этим, просто нажмите кнопку «Далее».

На данном экране вы можете выбрать те, компоненты wxPython, которые хотите установить. Обычно здесь следует согласиться с параметрами, предложенными по умолчанию. После этого, нажмите «Далее» и wxPython будет устанавливаться. Когда установка будет завершена, вы увидите следующее:

Это последнее диалоговое окно установщика. Я обычно убираю галочки с «README», так как я уже читал его. Если же вы хотите ознакомиться с этим файлом, то просто оставьте галочку. Остальные 2 варианта я оставляю выбранными. Когда вы нажмете «Завершено», вы заметите появление командной строки, в которой будет проносится масса текста. Это означает, что установщик компилирует различные скрипты Python в .pyc-файлы и добавляет пакетные скрипты.

После этого установку wxPython на Windows можно считать завершённой.

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Попробуйте запустить код, который вы видели в начале статьи. Вы должны будете увидеть что-то похожее на это:

Установка wxPython на Mac

wxPython поддерживает как 32-х так 64-х битную версию Mac OS. Если вдруг у вас установлена старая версия программного обеспечения Mac, вам скорее всего нужно установить версию Carbon для wxPython. Однако, Carbon не поддерживает 64-битную версию операционной системы Mac, поэтому если у вас установлена именно она, рекомендуется устанавливать версию Cocoa. Обратите внимание на то, что установка Classic будет осуществляется посредством dmg-файла.

После загрузки подходящей версии, вам нужно будет задать настройки безопасности Mac, позволяющие вам установить wxPython. Перейдите в System Preferences, нажав на яблоко в верхнем левом углу экрана:

Как только вы там окажетесь, найдите Security Settings. В строке поиска вам будут предложены подсказки:

Выберите Security Settings и нажмите на маленький замочек, расположенный в нижнем левом углу диалогового окна.

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

Теперь запустите загруженный вами dmg-установщик. Сразу же после установки wxPython верните настройки безопасности к прежним значениям. Это позволит избежать установки вредоносного программного обеспечения в будущем.

Чтобы проверить правильность установки wxPython, запустите скрипт, расположенный в начале статьи. Вы должны будете увидеть что-то вроде этого:

Установка wxPython на Linux

Установка wxPython на Linux является одним из наиболее сложных процессов на сегодняшний день. Долгое время вы могли использовать сопровождающие пакеты Linux для того, чтобы упаковать wxPython, а затем использовать менеджер пакетов Linux, чтобы установить wxPython.

wxPython уже доступен для установки через pip.

Установка нужных библиотек:

apt-get install -y libgtk2.0-dev libgtk-3-dev \
libjpeg-dev libtiff-dev \
libsdl1.2-dev libgstreamer-plugins-base0.10-dev \
libnotify-dev freeglut3 freeglut3-dev libsm-dev \
libwebkitgtk-dev libwebkitgtk-3.0-dev

apt-get install -y libgtk2.0-dev libgtk-3-dev \

libjpeg-dev libtiff-dev \

libsdl1.2-dev libgstreamer-plugins-base0.10-dev \

libnotify-dev freeglut3 freeglut3-dev libsm-dev \

libwebkitgtk-dev libwebkitgtk-3.0-dev

Устанавливаем wxPython:

Пакеты Docs и Demo для wxPython

Набор инструментов wxPython GUI также имеет демо-пакет, который вы можете загрузить. Для Windows и Mac существуют установщики. Сам пакет представляет собой коллекцию файлов Python, которые демонстрируют преимущественное большинство виджетов, идущих в комплекте с wxPython. Он также содержит документацию для wxPython и коллекцию программ, написанных с его помощью, среди которых IDE и программа для рисования. Данный пакет абсолютно бесценен в освоении новых виджетов. Я использую его каждый раз, когда хочу протестировать новый виджет и понять его принцип работы. Главным преимуществом является то, что вы можете модифицировать сам демо-пакет даже когда он запущен и наблюдать за тем, как это влияет на виджеты.

Подведем итоги

На данном этапе, вы уже должны довольно чётко понимать, как установить wxPython. В разделе wxPython мы рассмотрели множество различных вариантов, так что трудностей с установкой wxPython Classic на Windows, Mac и Linux у вас возникнуть не должно. Вы также знаете, как установить Phoenix с помощью одной простой команды с использованием pip. Следующий этап – установка wxPython на ваш компьютер и изучение других рецептов на сайте!

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.

E-mail: [email protected]

Образование
Universitatea Tehnică a Moldovei (utm.md)

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»

Как использовать wxPython для Python 3?

Я установил wxPython 3.0.1.1, но не могу import wx использовать Python 3.4.1 . Я получаю следующую ошибку:

Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 00:54:21) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information. 
>>> import wx
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'wx'

Тем не менее, я могу import wx , если использую Python 2.7 (установка по умолчанию в моем OS X 10.9 ):

Python 2.7.5 (default, Mar  9 2014, 22:15:05) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import wx
>>>

Как я могу использовать wxPython для Python 3, а конкретно для Python 3.4.1?

python

macos

python-3.x

wxpython

Поделиться

Источник


Nick    

08 октября 2014 в 07:08

5 ответов


  • wxPython для Python 2.4.3 на Windows 7

    Сервер моей компании использует Python 2.4.3. Мне нужно использовать wxPython, но текущая версия wxPython требует либо Python 2.6, либо 2.7. Как заставить wxPython работать с Python 2.4.3 на Windows 7? http://www.wxpython.org/скачать.php P.S. Я попытался установить wxPython2.8-win32-Юникод-py26 и…

  • wxpython 3 на windows

    Как я могу скачать wxPython 3 на windows? Я вижу эту ссылку, но она имеет расширение .egg, а не exe. Я отказался от pyQT из-за отсутствия продвинутых учебников для PyQT4, и мне действительно хотелось бы иметь хорошую библиотеку, из которой я могу построить GUI в Python. Я читал, что wxpython 3…



14

На вашем компьютере установлены два разных питона (3.4.1 и 2.7.5). Не ожидайте, что один пакет, установленный в одном python (wxPython 3.0.1.1 в python 2.7.5), будет автоматически доступен в другом python.

Кроме того, wxPython (классический) не работает для Python 3. Вам нужно wxPython Феникс , чтобы быть в состоянии сделать это.

EDIT: рекомендуемый способ (по @RobinDunn) установить wxPython (разновидность Феникса, которая будет работать на 2.7 и 3, Теперь размещенная на PyPI ) в настоящее время просто делает:

pip install wxPython

Если у вас установлена версия разработчика, просто сделайте следующее заранее:

pip uninstall wxPython_Phoenix

Вы можете попробовать установить один из снимков wxPython Phoenix в свой Python 3.4.1. Однако имейте в виду, что Phoenix не совместим с classic, и вы можете испытать ту или иную икоту при повторном использовании классического кода ( но переход его выполним и стоит того).

Вы можете найти полное объяснение/описание в следующем wxPython wiki по следующей ссылке:

Установка wxPython-Phoenix с использованием pip

Есть несколько важных моментов:

  • что pip / setuptool достаточно новый (> 6.x.x/> 12.x.x)

  • что сборки «inofficial», и поэтому pip отказывается его устанавливать: в основном вам нужно добавить --pre при установке с pip.

  • что вы отказываетесь от проверки SSL --trusted-host wxpython.org (больше не требуется в современных версиях, где https теперь работает должным образом).

Полная команда для машин Windows:

C:\python27\scripts\pip.exe install --upgrade --pre -f https://wxpython.org/Phoenix/snapshot-builds/ wxPython_Phoenix

Обратите внимание, что это установит wxPython Phoenix для Python 2.7.

Поделиться


nepix32    

08 октября 2014 в 08:09



7

Чтобы использовать wxPython с вашим Python 3.4x, вам нужно использовать wxPython Феникс-как указывали другие. Чтобы установить его вы можете сделать:

pip install -U --pre -f http://wxpython. org/Phoenix/snapshot-builds/ wxPython_Phoenix 

Обратите внимание на пробел после последнего ‘/’ и wxPython_Phoenix

Поделиться


Werner    

08 октября 2014 в 14:32



2

Как представляется, wxPython еще не полностью портирован для Python 3, хотя номер версии может предполагать это. Вот почему модули wx не добавляются в sys.path из Python 3.

Вы можете либо согласиться на использование wxPython из Python 2.7, либо взглянуть на эту запись SO: все еще нет wxPython для Python 3 (или 3.3)?
Вот что предложил @nepix32.

В качестве альтернативы используйте другую библиотеку GUI, которая работает с Python 3. Вот список .

Поделиться


jotrocken    

08 октября 2014 в 11:16


  • Может ли один проект Python использовать как код 2.x, так и код 3.x?

    Я собираюсь начать долгий (~1 год) программный проект в Python году. Я хочу использовать wxPython для моего GUI (поддерживает 2.6), но я также хочу использовать 3.1 для rest проекта (чтобы начать использовать синтаксис 3.x). Есть ли какой-нибудь способ для меня разработать проект, который…

  • wxPython в Python 3.4.1

    Я относительно новичок в программировании Python, поэтому заранее приношу извинения, если этот вопрос кажется глупым. Я пытаюсь загрузить новый редактор Python (drpython), который написан с помощью wxpython. У меня есть Python 3.4.1 64-bit на машине Windows 8.1. У меня сложилось впечатление, что…



0

Проверьте свой sys.path в переводчике :

import sys
sys.path

Если у вас нет нужной ссылки на нужный каталог, он не будет работать.

Кроме того, проверьте Lib/site-packages в вашем каталоге python, чтобы убедиться, что wx правильно установлен на вашем python 3. (должен быть каталог, начинающийся с «wx-3.0»)

Поделиться


inirlan    

08 октября 2014 в 07:30



0

Возможно, приведенные ранее решения работали и раньше. Но то, что сработало для меня сегодня (1 июня 2017 года), было:

pip install - U - - pre - f https://wxpython.org/Phoenix/snapshot-builds/ wxPython

Всегда проверяйте Readme.txt для этого…

Поделиться


Seyi Shoboyejo    

01 июня 2017 в 09:31


Похожие вопросы:

С WXPython когда необходимо использовать классы?

Я очень новичок в python, и у меня есть какой-то глупый вопрос, Спасибо за помощь! когда я ищу в интернете о wxpython вопросах, я вижу, что почти 100% людей используют класс для wxpython. Из книги,…

wxPython для Python 3

Есть ли у wxPython версия для Python 3? Если да, то где я могу его достать?

Все еще нет wxPython для Python 3 (или 3.3)?

Я хотел начать работать с wxPython, но обнаружил, что он не обновляется для Python 3. Я использую новейшую версию Python, то есть 3.3. Поэтому я начал искать в интернете и нашел некоторых людей,…

wxPython для Python 2.4.3 на Windows 7

Сервер моей компании использует Python 2.4.3. Мне нужно использовать wxPython, но текущая версия wxPython требует либо Python 2.6, либо 2.7. Как заставить wxPython работать с Python 2.4.3 на Windows…

wxpython 3 на windows

Как я могу скачать wxPython 3 на windows? Я вижу эту ссылку, но она имеет расширение .egg, а не exe. Я отказался от pyQT из-за отсутствия продвинутых учебников для PyQT4, и мне действительно…

Может ли один проект Python использовать как код 2.x, так и код 3.x?

Я собираюсь начать долгий (~1 год) программный проект в Python году. Я хочу использовать wxPython для моего GUI (поддерживает 2.6), но я также хочу использовать 3.1 для rest проекта (чтобы начать…

wxPython в Python 3.4.1

Я относительно новичок в программировании Python, поэтому заранее приношу извинения, если этот вопрос кажется глупым. Я пытаюсь загрузить новый редактор Python (drpython), который написан с помощью…

wxPython на Python 3 среда Miniconda

Опробовать wxPython Phoenix для Python 3.3 на OS X. (Я не уверен, какую версию Python 3 Phoenix поддерживает, я принудительно устанавливаю ее. >>> import wx >>> wx.App() This…

установите еще один wxpython для python 32bit

Я запускаю 2 установки python 2.7 на своем mac. первый-это python 64 байта, где установлен wxpython, а второй python-32 байта, где я также хочу установить wxpython. обратите внимание, что мои…

wxPython virtualenv python 3

Я пытаюсь перенести свои проекты с Python 2.7.12 на Python 3.5.2. (Это правильно, не так ли?) Я понимаю, что заставить wxPython работать в virtualenv может быть проблемой, но он отлично работает на…

wxPython — Краткое руководство — CoderLessons.com

wxPython — это оболочка Python для wxWidgets (написана на C ++), популярного кроссплатформенного инструментария GUI. Разработанный Робином Данном и Харри Пасаненом, wxPython реализован как модуль расширения Python.

Как и wxWidgets, wxPython также является бесплатным программным обеспечением. Его можно скачать с официального сайта http://wxpython.org. Двоичные файлы и исходный код для многих платформ операционных систем доступны для загрузки на этом сайте.

Основные модули в API wxPython включают основной модуль. Он состоит из класса wxObject , который является основой для всех классов в API. Модуль управления содержит все виджеты, используемые при разработке приложений с графическим интерфейсом. Например, wx.Button, wx.StaticText (аналог метки), wx.TextCtrl (редактируемый текстовый элемент управления) и т. Д.

API wxPython имеет модуль 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-документы-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 в рамку.

  • Добавьте объект StaticText для отображения «Hello World» в желаемой позиции внутри окна.

  • Активируйте окно фрейма методом show ().

  • Введите основной цикл событий объекта Application.

Импортировать модуль wx.

Определить объект класса Application.

Создайте окно верхнего уровня как объект класса wx.Frame. Параметры заголовка и размера указаны в конструкторе.

Хотя другие элементы управления могут быть добавлены в объект Frame, их макет не может управляться. Следовательно, поместите объект Panel в рамку.

Добавьте объект 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 является наиболее часто используемым окном верхнего уровня. Он является производным от класса wxWindow . Фрейм — это окно, размер и положение которого могут быть изменены пользователем. Имеет строку заголовка и кнопки управления. При необходимости могут быть включены другие компоненты, такие как строка меню, панель инструментов и строка состояния. Окно wxFrame может содержать любой кадр, который не является диалогом или другим кадром.

Создание привлекательного графического интерфейса с помощью ручного кодирования может быть утомительным. Визуальный дизайнер GUI всегда удобен. Доступны многие IDE разработки для GUI, ориентированные на wxPython. Ниже приведены некоторые из них —

  • wxFormBuilder
  • wxDesigner
  • wxGlade
  • Боконстрактор
  • gui2py

wxFormBuilder — это кроссплатформенный WYSIWYG GUI-конструктор с открытым исходным кодом, который может переводить дизайн wxWidget GUI в формат 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 & Choice Class

Объект 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.Notebook

Виджет wx.Notebook представляет элемент управления с вкладками. Один объект Notebook в рамке имеет одну или несколько вкладок (называемых страницами), каждая из которых имеет панель, отображающую макет элементов управления.

14 wx.SplitterWindow

Объект этого класса является менеджером макета, который содержит два подокна, размер которых можно динамически изменять, перетаскивая границы между ними. Элемент управления Splitter предоставляет ручку, которую можно перетаскивать для изменения размера элементов управления.

15 HTMLWindow

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

16 ListBox & ListCtrl

Виджет wx.ListBox представляет вертикально прокручиваемый список строк. По умолчанию можно выбрать один элемент в списке. Виджет ListCtrl — сильно улучшенный инструмент отображения и выбора списка. Список из более чем одного столбца может быть отображен в виде отчета, списка или значка.

Класс wx.Frame имеет конструктор по умолчанию без аргументов.

Класс wx.Panel обычно помещается внутри объекта wxFrame. Этот класс также унаследован от класса wxWindow.

Объект класса wx.StaticText представляет элемент управления, содержащий такой текст только для чтения. Его можно назвать пассивным контролем, поскольку он не производит никаких событий.

В wxPython объект класса wx.TextCtrl служит для этой цели. Это элемент управления, в котором текст может отображаться и редактироваться.

Каждая кнопка, объект класса wx.RadioButton, несет текстовую метку рядом с круглой кнопкой. API wxPython также состоит из класса wx.RadioBox. Его объект предлагает границу и метку для группы.

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

Объект wx.ComboBox представляет список элементов для выбора. Он может быть настроен как выпадающий список или с постоянным отображением. API wxPython содержит класс wx.Choice, объект которого также является раскрывающимся списком, который постоянно доступен только для чтения.

Объект класса Wx.Gauge показывает вертикальную или горизонтальную полосу, которая графически показывает возрастающую величину.

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

Горизонтальная полоса чуть ниже строки заголовка окна верхнего уровня зарезервирована для отображения серии меню. Это объект класса wx.MenuBar в API wxPython.

Если для параметра стиля объекта wx.Toolbar установлено значение wx.TB_DOCKABLE, он становится закрепляемым. Плавающая панель инструментов также может быть построена с использованием класса AUIToolBar wxPython.

Хотя объект класса Dialog выглядит как фрейм, он обычно используется как всплывающее окно поверх родительского фрейма. Целью диалога является сбор некоторых данных от пользователя и отправка их в родительский фрейм.

Виджет wx.Notebook представляет элемент управления с вкладками. Один объект Notebook в рамке имеет одну или несколько вкладок (называемых страницами), каждая из которых имеет панель, отображающую макет элементов управления.

Объект этого класса является менеджером макета, который содержит два подокна, размер которых можно динамически изменять, перетаскивая границы между ними. Элемент управления Splitter предоставляет ручку, которую можно перетаскивать для изменения размера элементов управления.

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

Виджет wx.ListBox представляет вертикально прокручиваемый список строк. По умолчанию можно выбрать один элемент в списке. Виджет ListCtrl — сильно улучшенный инструмент отображения и выбора списка. Список из более чем одного столбца может быть отображен в виде отчета, списка или значка.

В отличие от приложения в консольном режиме, которое выполняется последовательно, приложение на основе графического интерфейса пользователя управляется событиями. Функции или методы выполняются в ответ на действия пользователя, такие как нажатие кнопки, выбор элемента из коллекции или щелчок мыши и т. Д., Называемые событиями.

Данные, относящиеся к событию, которое происходит во время выполнения приложения, сохраняются как объект подкласса, производного от wx.Event . Элемент управления отображением (например, Button) является источником события определенного типа и создает связанный с ним объект класса Event. Например, нажатие кнопки генерирует wx.CommandEvent. Эти данные события отправляются методу обработчика события в программе. У wxPython есть много предопределенных связывателей событий. Связыватель событий инкапсулирует отношения между конкретным виджетом (элементом управления), связанным с ним типом события и методом обработчика события.

Например, чтобы вызвать метод OnClick () программы для события нажатия кнопки, требуется следующий оператор:

self.b1.Bind(EVT_BUTTON, OnClick)

Метод Bind () наследуется всеми экранными объектами из класса wx.EvtHandler. EVT_.BUTTON — это механизм связывания, который связывает событие нажатия кнопки с методом OnClick ().

пример

В следующем примере MoveEvent, вызванное перетаскиванием окна верхнего уровня (в данном случае это объект wx.Frame), подключается к методу OnMove () с помощью связывателя 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

wxKeyEvent

Происходит при нажатии или отпускании клавиши

wxPaintEvent

Генерируется всякий раз, когда необходимо перерисовать содержимое окна

wxMouseEvent

Содержит данные о любом событии из-за активности мыши, например нажатие или перетаскивание кнопки мыши

wxScrollEvent

Связано с элементами прокрутки, такими как wxScrollbar и wxSlider

wxCommandEvent

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

wxMenuEvent

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

wxColourPickerEvent

wxColourPickerCtrl сгенерированные события

wxDirFilePickerEvent

События, сгенерированные FileDialog и DirDialog

События в wxPython бывают двух типов. Основные события и командные события. Базовое событие остается локальным по отношению к окну, в котором оно происходит. Большинство wxWidgets генерируют командные события. Событие команды может быть передано в окно или окна, которые находятся выше исходного окна в иерархии классов.

пример

Ниже приведен простой пример распространения событий. Полный код —

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.

GUI-виджет можно разместить внутри окна контейнера, указав его абсолютные координаты, измеренные в пикселях. Координаты относятся к размерам окна, определяемым аргументом размера его конструктора. Положение виджета внутри окна определяется аргументом 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()

Это абсолютное позиционирование, однако, не подходит по следующим причинам:

  • Положение виджета не изменяется даже при изменении размера окна.

  • Внешний вид может быть неодинаковым на разных устройствах отображения с разным разрешением.

  • Модификация в макете сложна, так как может потребоваться перепроектирование всей формы.

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

Внешний вид может быть неодинаковым на разных устройствах отображения с разным разрешением.

Модификация в макете сложна, так как может потребоваться перепроектирование всей формы.

API wxPython предоставляет классы Layout для более элегантного управления позиционированием виджетов внутри контейнера. Преимущества менеджеров по расположению над абсолютным позиционированием:

  • Виджеты внутри окна автоматически изменяются.
  • Обеспечивает равномерное отображение на устройствах отображения с различными разрешениями.
  • Динамическое добавление или удаление виджетов возможно без изменения дизайна.

Менеджер раскладки называется Sizer в wxPython. Wx.Sizer является базовым классом для всех подклассов 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 помещает блок размеров в статический блок. Он обеспечивает рамку вокруг рамки и метку сверху.

Этот измеритель позволяет расположить элементы управления в ряд или столбец. Макет BoxSizer определяется его аргументом ориентации (wxVERTICAL или wxHORIZONTAL).

Как следует из названия, объект GridSizer представляет двумерную сетку. Элементы управления добавляются в слот сетки в порядке слева направо и сверху вниз.

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

GridBagSizer — универсальный классификатор. Он предлагает больше улучшений, чем FlexiGridSizer. Дочерний виджет может быть добавлен в определенную ячейку в сетке.

StaticBoxSizer помещает блок размеров в статический блок. Он обеспечивает рамку вокруг рамки и метку сверху.

Виджет кнопки наиболее широко используется в любом интерфейсе GUI. Он фиксирует событие нажатия, созданное пользователем. Его наиболее очевидное использование — запуск связанной с ним функции-обработчика.

Библиотека классов 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

Установить по умолчанию()

Кнопка установлена ​​по умолчанию для окна верхнего уровня. Эмулирует событие нажатия при нажатии клавиши Enter

SetLabel ()

Устанавливает заголовок кнопки программно

GetLabel ()

Возвращает заголовок кнопки

Установить по умолчанию()

Кнопка установлена ​​по умолчанию для окна верхнего уровня. Эмулирует событие нажатия при нажатии клавиши Enter

Два важных метода класса wx.ToggleButton —

SN Методы и описание
1

ПолучитьЗначение ()

Возвращает состояние переключателя (вкл / выкл)

2

SetValue ()

Устанавливает состояние кнопки программно

ПолучитьЗначение ()

Возвращает состояние переключателя (вкл / выкл)

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)

Примечание. Из-за флага 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 () извлекает метку кнопки источника, которая вызвала событие click. Эта этикетка напечатана на консоли.

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 установлены.

  • Направление — сверху, снизу, слева, справа или по центру

  • Положение — внутри закрепляемого региона можно разместить несколько панелей. Каждому дается номер позиции.

  • Строка — в одной строке отображается несколько панелей. Точно так же, как несколько панелей инструментов появляются в одной строке.

  • Слой. Панели можно размещать слоями.

Направление — сверху, снизу, слева, справа или по центру

Положение — внутри закрепляемого региона можно разместить несколько панелей. Каждому дается номер позиции.

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

Слой. Панели можно размещать слоями.

Используя эту 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 ( интерфейс с одним документом ). Это требует больше ресурсов памяти, так как каждое окно может иметь свою собственную систему меню, панель инструментов и т. Д.

Инфраструктура 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 & plus; (Интерфейс графического рисования), библиотеки CoreGraphics и Cairo составляют основу API рисования в wxPython. wx.GraphicsContext — это основной рисуемый объект, с помощью которого создаются различные объекты Device Context.

wx.DC — абстрактный класс. Его производные классы используются для визуализации графики и текста на разных устройствах. Классы Device Context являются —

  • wx.ScreenDC — Используйте это, чтобы рисовать на экране, в отличие от отдельного окна.

  • wx.ClientDC — Используйте это, чтобы рисовать в клиентской области окна (часть без границ и других украшений), но не используйте его изнутри wxPaintEvent.

  • wx.PaintDC — Используйте это, чтобы рисовать в клиентской области окна, но только изнутри wxPaintEvent.

  • wx.WindowDC — Используйте это, чтобы рисовать на всей области окна, включая украшения. Это может быть недоступно на платформах, отличных от Windows.

wx.ScreenDC — Используйте это, чтобы рисовать на экране, в отличие от отдельного окна.

wx.ClientDC — Используйте это, чтобы рисовать в клиентской области окна (часть без границ и других украшений), но не используйте его изнутри wxPaintEvent.

wx.PaintDC — Используйте это, чтобы рисовать в клиентской области окна, но только изнутри wxPaintEvent.

wx.WindowDC — Используйте это, чтобы рисовать на всей области окна, включая украшения. Это может быть недоступно на платформах, отличных от Windows.

API рисования wxPython предлагает различные функции для рисования формы, текста и изображения. Объекты, необходимые для рисования, такие как Color, Pen, Brush и Font, также могут быть построены с использованием классов GDI.

wx.Colour Class

Цветовой объект представляет собой комбинацию значений интенсивности RGB (красный, зеленый и синий), каждое по шкале 0-255. Есть несколько предопределенных цветовых объектов, таких как —

  • wxBLACK
  • wxBLUE
  • wxCYAN
  • wxGREEN
  • wxYELLOW
  • wxLIGHT_GREY
  • wxRED
  • wxWHITE

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

wx.Colour(r,g,b)

wx.Pen Class

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

Предопределенные объекты Pen

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

Предопределенные стили пера

wx.SOLID
wx.DOT
wx.LONG_DASH
wx.SHORT_DASH
wx.DOT_DASH
wx.TRANSPARENT

Wx.Brush Class

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

Для пользовательского объекта 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 ()

Отображает данный текст в указанной позиции

DrawRectangle ()

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

DrawCircle ()

Рисует круг в данной точке как центр и радиус

DrawEllipse ()

Рисует эллипс с заданным радиусом x и y

DrawLine ()

Рисует линию между двумя объектами wx.Point

DrawBitmap ()

Нарисуйте изображение в заданной позиции

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()

Приведенный выше код производит следующий вывод —

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

Операция перетаскивания включает в себя следующие шаги:

  • Объявите цель отбрасывания
  • Создать объект данных
  • Создать 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()

Приведенный выше код производит следующий вывод —

Как создать приложение с графическим интерфейсом пользователя Python с помощью wxPython

Графический интерфейс пользователя или GUI — это пользовательский интерфейс, который включает в себя графические элементы, которые позволяют человеку общаться с электронными устройствами, такими как компьютеры, портативные устройства и другие устройства. Он отображает информацию с помощью значков, меню и графики. Они обрабатываются с помощью указывающего устройства, такого как мышь, трекбол или стилус.

Графический интерфейс пользователя — это в основном приложение с окнами, кнопками и множеством других виджетов, которые позволяют пользователю взаимодействовать с вашим приложением.Веб-браузер — это типичный пример графического интерфейса пользователя, в котором есть кнопки, вкладки и главное окно, а также где отображается контент.

Он был разработан исследовательской лабораторией Xerox Palo Alto в конце 1970-х годов. Сегодня каждая ОС имеет свой собственный графический интерфейс. Программные приложения используют их и разрабатывают свои собственные графические интерфейсы.

Python содержит множество наборов инструментов с графическим интерфейсом, среди которых наиболее важными являются Tkinter, wxPython и PyQt. Все эти инструменты имеют возможность работать с Windows, macOS и Linux с дополнительным качеством работы на мобильных телефонах.

Как начать работу с wxPython?

wxPython был впервые выпущен в 1998 году. Это кроссплатформенный инструментарий Python с открытым исходным кодом, используемый в качестве класса-оболочки для библиотеки C ++ под названием wxWidgets. Основная особенность wxPython, которая отличается от других наборов инструментов, таких как PyQt и Tkinter, заключается в том, что он использует фактические виджеты на собственной платформе там, где это необходимо. Это позволяет приложениям wxPython выглядеть родными для операционной системы, в которой они работают.

Набор инструментов wxPython содержит множество основных виджетов, а также множество настраиваемых виджетов, которые вы можете загрузить из раздела «Дополнительные файлы» на официальной странице wxPython.

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

Установка wxPython

Вы будете использовать последнюю версию wxPython, wxPython 4, которую также называют Project Phoenix wxPython. Это новая реализация wxPython, направленная на повышение скорости, удобства обслуживания и расширяемости wxPython.WxPython 3 и wxPython 2 были созданы только для Python 2. Сопровождающий wxPython отклонил множество псевдонимов и очистил много кода, чтобы сделать wxPython более простым и понятным для Python.

Если вы переходите со старой версии wxPython на wxPython 4, обратите внимание на следующие ссылки:

Версия Phoenix совместима как с Python 2.7, так и с Python 3. Вы можете использовать pip для установки wxPython 4:

 $ pip install wxpython 

Вы получите раздел предварительных требований на странице Github wxPython, который предоставит информацию для установки wxPython в системах Linux.

Вы также можете заглянуть в раздел Extras Linux, чтобы узнать о колесах Python для версий GTK2 и GTK3. Чтобы установить одно из колес, используйте команду ниже:

 $ pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04/ wxPython 

Не забудьте изменить команда для соответствия версии Linux.

Компоненты графического интерфейса пользователя

Как упоминалось ранее, графический интерфейс пользователя — это не что иное, как интерфейс, позволяющий взаимодействовать с пользователем.

Общие компоненты пользовательских интерфейсов:

  • Главное окно.
  • Меню.
  • Панель инструментов.
  • Кнопки.
  • Ввод текста.
  • Этикетки.

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

Циклы событий

Графический интерфейс пользователя работает, ожидая, пока пользователь выполнит действие. Это называется событием. Событие происходит, когда что-то вводится пользователем или когда пользователь использует свою мышь, чтобы нажать кнопку или какой-либо виджет, когда приложение находится в фокусе.

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

При программировании графического пользовательского интерфейса не забудьте прикрепить виджеты к обработчикам событий, чтобы ваше приложение что-то делало.

Вы также можете заблокировать цикл обработки событий, чтобы GUI не отвечал, что для пользователя будет казаться зависшим.Об этом следует помнить при работе с циклами событий. Запускайте специальный поток или процесс, когда графическому интерфейсу требуется больше четверти секунды для запуска процесса.

Фреймворки wxPython содержат специальные потокобезопасные методы, которые вы можете использовать для обратной связи с вашим приложением. Это сообщает, что поток завершен или ему дано обновление.

Как создать приложение-скелет?

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

Пример создания приложения Hello World с Python:

 import wx

application = wx.App ()
framework = wx.Frame (родительский = None, title = 'Hello World')
framework.Show ()
app.MainLoop () 

В приведенном выше примере есть две части программы — wx.App и wx.Frame. Первый — это объект приложения wxPython, который в основном необходим для работы с графическим интерфейсом. Он запускает .MainLoop (), который представляет собой цикл событий, который вы узнали ранее.

Последняя часть создает окно для взаимодействия с пользователем. Он сообщает wxPython, что у фрейма нет родителя и его заголовок — Hello World. Если вы запустите приведенный выше код, он будет выглядеть так:

Приложение будет выглядеть иначе, если вы запустите его в Mac или Linux.

Примечание. Пользователи Mac могут получить следующее сообщение: Этой программе требуется доступ к экрану.Пожалуйста, запускайте со сборкой Python Framework, и только когда вы вошли в систему на основном дисплее вашего Mac. Если вы видите это сообщение и не работаете в виртуальном окружении, вам необходимо запустить приложение с помощью pythonw вместо python. Если вы запускаете wxPython из виртуального окружения, обратитесь к вики-странице wxPython, чтобы найти решение.

Свертывание, развертывание и выход будут включены в wx.Frame по умолчанию. Однако большая часть кода wxPython потребует от вас создания wx.Frame в качестве подкласса и других виджетов, чтобы использовать всю мощь инструментария.

Давайте перепишем код, используя class:

 import wx

класс MyFramework (wx.Frame):
def frame (self):
super (). frame (parent = None, title = 'Hello World')
self.Show ()

если __name__ == '__main__':
application = wx.App ()
framework = MyFramework ()
application.MainLoop () 

Этот код можно использовать в качестве шаблона для вашего приложения.

Виджеты в wxPython

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

Теперь давайте добавим кнопку и позволим пользователю вводить текст, добавив текстовое поле:

 import wx

класс MyFramework (wx.Frame):
def frame (self):
super (). frame (parent = None, title = 'Hello World')
панель = wx.Panel (самостоятельно)

себя.text_ctrl = wx.TextCtrl (панель, pos = (5, 5))
my_button = wx.Button (панель, label = 'Press Me', pos = (5, 55))

self.Show ()

если __name__ == '__main__':
application = wx.App ()
framework = MyFramework ()
application.MainLoop () 

Когда вы запустите код, приложение будет выглядеть так:

Первый виджет, рекомендуемый в Windows, — это wx. Panel. Это делает цвет фона рамки правильным оттенком серого. Переход по табуляции отключен без панели в Windows.

Если панель является единственным дочерним элементом фрейма, она будет автоматически расширена, чтобы заполнить фрейм самим собой. Следующее, что вам нужно сделать, это добавить на панель wx.TextCtrl. Первым аргументом всегда является то, к какому родительскому элементу должен перейти виджет почти для всех виджетов. Поэтому, если вы хотите сохранить текстовый элемент управления и кнопку в верхней части панели, вам необходимо указать родительский элемент.

Вам также необходимо сообщить wxPython о позиции виджета. Вы можете сделать это с помощью параметра pos.Местоположение по умолчанию — (0,0), что на самом деле находится в верхнем левом углу родительского элемента. Таким образом, чтобы изменить текстовый элемент управления, вы можете изменить положение кадра, вы можете сместить его левый угол на 5 пикселей слева (x) и на 5 пикселей сверху (y). Наконец, вы можете добавить свою кнопку на панель и пометить ее. Вы также можете установить y-координату на 55, чтобы предотвратить перекрытие виджетов.

Абсолютное позиционирование

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

Могут возникнуть ситуации, когда вам нужно отслеживать все ваши виджеты и перемещать виджеты в случае сложного приложения. Это может быть очень непросто. Однако большинство современных наборов инструментов предоставляют решение для этой проблемы, которое мы изучим позже.

Сайзеры (динамическое изменение размеров)

Сайзеры — это методы определения компоновки элементов управления в диалоговых окнах wxPython. У них есть возможность создавать диалоги, не зависящие от платформы. Они управляют расположением виджетов и корректируют их, когда пользователь изменяет размер окна приложения.

Вот некоторые из основных типов, которые обычно используются:

  • wx.BoxSizer
  • wx.GridSizer
  • wx.FlexGridSizer

Пример кода для добавления wx.BoxSizer к предыдущему коду:

 import wx

класс MyFramework (wx.Frame):
def frame (self):
super (). frame (parent = None, title = 'Hello World')
панель = wx.Panel (самостоятельно)
my_sizer = wx.BoxSizer (wx.VERTICAL)
self.text_ctrl = wx.TextCtrl (панель)
my_sizer.Add (self.text_ctrl, 0, wx.ALL | wx.EXPAND, 5)
my_button = wx.Button (панель, label = 'Press Me')
my_sizer.Add (my_btn, 0, wx.ALL | wx.CENTER, 5)
panel.SetSizer (my_sizer)
self.Show ()

если __name__ == '__main__':
application = wx.App ()
framework = MyFramework ()
application.MainLoop () 

В приведенном выше примере создается экземпляр wx.BoxSixer, который передается в wx.VERTICAL, что на самом деле является ориентацией, которую виджеты включаются в классификатор.Виджеты будут добавлены вертикально сверху вниз. Вы также можете установить ориентацию BoxSizer на wx.HORIZONTAL. В этом случае виджеты добавляются слева направо.

Вы можете использовать .Add () для виджета в классификаторе, который принимает максимум пять аргументов, как показано ниже:

  • окно (виджет) — это виджет, который добавляется в классификатор.
  • пропорция — Устанавливает, сколько места, соответствующего другим виджетам в классификаторе, будет занимать виджет.По умолчанию пропорция равна нулю, что оставляет wxPython в исходной пропорции.
  • flag — позволяет передавать несколько флагов, разделяя их вертикальной чертой: |. Текстовый элемент управления добавляется с помощью флагов wx.ALL и wx.EXPAND. Флаг wx.ALL добавляет рамку со всех сторон виджета. С другой стороны, wx.EXPAND расширяет виджеты настолько, насколько может быть расширен классификатор.
  • border — Этот параметр сообщает wxPython о количестве пикселей границы, необходимых вокруг виджета.
  • userData — это редкий аргумент, который используется для изменения размера в случае сложных приложений.

Однако в этом примере флаг wx.EXPAND заменен на wx.CENTER для отображения кнопки в центре экрана.

Когда вы запустите код, ваше приложение будет выглядеть примерно так:

Добавление события с помощью wxPython

Хотя ваше приложение выглядит круто, но на самом деле ничего не делает. Созданная вами кнопка ничего не делает при ее нажатии.Дадим кнопке задание:

 import wx

класс MyFramework (wx.Frame):
def frame (self):
super (). frame (parent = None, title = 'Hello World')
панель = wx.Panel (самостоятельно)
my_sizer = wx.BoxSizer (wx.VERTICAL)
self.text_ctrl = wx.TextCtrl (панель)
my_sizer.Add (self.text_ctrl, 0, wx.ALL | wx.EXPAND, 5)
my_button = wx.Button (панель, label = 'Press Me')
my_button.Bind (wx.EVT_BUTTON, self.on_press)
my_sizer.Add (my_btn, 0, wx.ВСЕ | wx.CENTER, 5)
panel.SetSizer (my_sizer)
self.Show ()

def button_press (self, event):
значение = self.text_ctrl.GetValue ()
если не значение:
print ("Вы ничего не ввели!")
еще:
print (f'Вы набрали: "{значение}" ')

если __name__ == '__main__':
application = wx.App ()
framework = MyFramework ()
application.MainLoop () 

Вы можете прикреплять привязки событий к виджетам в wxPython.Это позволяет им реагировать на определенные типы событий.

Если вы хотите, чтобы кнопка что-то делала, вы можете сделать это с помощью метода кнопки .Bind () . Требуются события, к которым вы хотите привязаться, обработчик для вызова события, необязательный источник и ряд необязательных идентификаторов. В приведенном выше примере объект кнопки привязан к wx.EVT_BUTTON и получает указание вызвать button_press при срабатывании события.

.button_press также принимает второй аргумент по соглашению, который называется событием.Параметр события предполагает, что второй аргумент должен быть объектом события.

Вы можете получить содержимое текстового элемента управления с помощью метода GetValue () в .button_press.

Как создать рабочее приложение?

Рассмотрим ситуацию, когда вас просят создать редактор тегов MP3. Первое, что вам нужно сделать, — это найти необходимые пакеты.

Рассмотрим ситуацию, когда вас просят создать редактор тегов MP3. Первое, что вам нужно сделать, это найти необходимые пакеты.

Если вы выполните поиск в Google редактора тегов mp3 Python, вы найдете несколько вариантов, как показано ниже:

Из них eyeD3 — лучший выбор, чем два других, поскольку он имеет довольно хороший API, который можно использовать не увязнув в спецификации MP3 ID3.

Вы можете установить eyeD3 с помощью pip из вашего терминала:

 pip install eyed3 

Если вы хотите установить eyeD3 в macOS, вам необходимо установить libmagic с помощью brew.Пользователи Linux и Windows могут легко установить с помощью упомянутой выше команды.

Проектирование пользовательского интерфейса с помощью wxPython

Самое первое, что вы должны сделать перед проектированием интерфейса, — это набросать набросок того, как, по вашему мнению, должен выглядеть интерфейс.

Пользовательский интерфейс должен выполнять следующие задачи:

  • Открывать один или несколько файлов MP3.
  • Показать текущие теги MP3.
  • Отредактируйте тег MP3.

Если вы хотите открыть файл или папку, вам необходимо иметь меню или кнопку в вашем пользовательском интерфейсе.Вы можете сделать это с помощью меню «Файл». Вам также понадобится виджет, чтобы видеть теги для нескольких файлов MP3. Табличная структура, состоящая из столбцов и строк, была бы идеальной для этого случая, поскольку вы можете пометить столбцы для тегов MP3. Набор инструментов wxPython состоит из нескольких виджетов для выполнения этой задачи:

wx.ListCtrl будет лучшим вариантом из этих двух, поскольку виджет Grid является избыточным и сложным по своей природе. Наконец, вы можете использовать кнопку для выполнения задач редактирования.

Ниже показано, как должно выглядеть приложение:

Создание пользовательского интерфейса

При создании пользовательского интерфейса вы можете использовать множество подходов.Вы можете следовать шаблону проектирования модель-представление-контроллер, который используется для разработки пользовательских интерфейсов, который разделяет логику программы на три взаимосвязанных элемента. Вы должны знать, как разделять классы и сколько классов должно быть включено в один файл и так далее.

Однако в этом случае вам нужны только два класса:

  • wx.Panel class
  • wx.Frame class

Начнем с импорта и класса панели:

 import глазами3
импортный глобус
импорт wx

класс Mp3Panel (wx.Панель):
def frame (self, parent):
super () .__ init __ (родитель)
main_sizer = wx.BoxSizer (wx.VERTICAL)
self.row_obj_dict = {}

self.list_ctrl = wx.ListCtrl (
self, size = (- 1, 100),
style = wx.LC_REPORT | wx.BORDER_SUNKEN
)
self.list_ctrl.InsertColumn (0, 'Художник', ширина = 140)
self.list_ctrl.InsertColumn (1, 'Альбом', ширина = 140)
self.list_ctrl.InsertColumn (2, 'Заголовок', ширина = 200)
main_sizer.Add (self.list_ctrl, 0, wx.ВСЕ | wx.EXPAND, 0)
edit_button = wx.Button (self, label = 'Изменить')
edit_button.Bind (wx.EVT_BUTTON, self.on_edit)
main_sizer.Add (edit_button, 0, wx.ALL | wx.CENTER, 5)
self.SetSizer (main_sizer)

def on_edit (себя, событие):
print ('в on_edit')

def update_mp3_listing (self, folder_path):
print (folder_path) 

В приведенном выше примере импортируются пакет eyed3, пакет glob и пакет wx . Затем пользовательский интерфейс создается путем создания wx. Панель подкласса. Словарь row_obj_dict создан для хранения данных о MP3.

Следующее, что вам нужно сделать, это создать wx.ListCtrl и установить его в режим отчета, то есть wx.LC_REPORT. Этот флаг отчета является самым популярным среди всех, но вы также можете выбрать свой собственный в зависимости от флага стиля, который вы передаете. Теперь вам нужно позвонить по номеру . InsertColumn (), чтобы ListCtrl имел правильные заголовки, а затем предоставил индекс столбца, его метку и ширину пикселей столбца.

Наконец, вам нужно добавить кнопку «Изменить», обработчик событий и метод. Код для кадра следующий:

 класс Mp3Frame (wx.Frame):
def__init __ (сам):
super () .__ init __ (parent = None,
title = 'Редактор тегов Mp3')
self.panel = Mp3Panel (сам)
self.Show ()

если __name__ == '__main__':
app = wx.App (Ложь)
frame = Mp3Frame ()
app.MainLoop () 

Эта функция класса — лучший и более простой подход, чем предыдущий, потому что вам просто нужно установить заголовок фрейма и создать экземпляр класса панели MP3Panel.После всех реализаций пользовательский интерфейс будет выглядеть следующим образом:

Следующее, что мы сделаем, это добавим меню «Файл», чтобы добавить файлы MP3 в приложение, а также отредактировать их теги.

Создание работающего приложения

Самое первое, что вам нужно сделать, чтобы ваше приложение заработало, — это обновить класс wx.Frame, включив в него меню «Файл», которое позволит вам добавлять файлы MP3.

Код для добавления строки меню в наше приложение:

 class Mp3Frame (wx.Рамка):

def__init __ (сам):
wx.Frame .__ init __ (self, parent = None,
title = 'Редактор тегов Mp3')
self.panel = Mp3Panel (сам)
self.create_menu ()
self.Show ()

def create_menu (сам):
menu_bar = wx.MenuBar ()
file_menu = wx.Menu ()
open_folder_menu_item = file_menu.Append (
wx.ID_ANY, "Открыть папку",
"Открыть папку с MP3"
)
menu_bar.Append (file_menu, '& Файл')
self. Bind (
событие = wx.EVT_MENU,
handler = self.on_open_folder,
source = open_folder_menu_item,
)
self.SetMenuBar (панель_меню)

def on_open_folder (я, событие):
title = "Выберите каталог:"
dlg = wx.DirDialog (self, title,
style = wx.DD_DEFAULT_STYLE)
если dlg.ShowModal () == wx.ID_OK:
self.panel.update_mp3_listing (dlg.GetPath ())
dlg.Destroy () 

В приведенном выше примере кода .create_menu () вызывается в конструкторе класса, а затем в двух экземплярах — wx.MenuBar и wx.Menu созданы.

Теперь, если вы хотите добавить элемент в меню, вам нужно вызвать .Append () экземпляра меню и передать следующие вещи:

  • Уникальный идентификатор
  • Метка
  • Строка справки

После этого вызовите строку меню .Append () , чтобы добавить меню в строку меню. Это займет экземпляр меню и метку для меню. Метка называется & File, поэтому создается сочетание клавиш для открытия меню File , используя только клавиатуру.

Теперь вызывается self.Bind () для привязки кадра к wx.EVT_MENU. Это сообщает wxPython о том, какой обработчик следует использовать и к какому источнику привязать обработчик. Наконец, вызовите .SetMenuBar фрейма и передайте ему экземпляр строки меню. Ваше меню теперь добавлено во фрейм.

Теперь вернемся к обработчику события пункта меню:

 def on_open_folder (self, event):
title = "Выберите каталог:"
dlg = wx.DirDialog (self, title, style = wx.DD_DEFAULT_STYLE)
если dlg.ShowModal () == wx.ID_OK:
self.panel.update_mp3_listing (dlg.GetPath ())
dlg.Destroy () 

Вы можете использовать wx.DirDialog wxPython, чтобы выбрать каталоги правильной папки MP3. Чтобы отобразить диалоговое окно, используйте .ShowModal (). Это отобразит диалоговое окно модально, но не позволит пользователю взаимодействовать с основным приложением. Вы можете перейти к выбранному пользователем пути с помощью .GetPath () всякий раз, когда пользователь нажимает кнопку OK. Этот путь нужно добавить в класс панели, и это может сделать панель.update_mp3_listing ().

Наконец, вам нужно закрыть диалоговое окно, и лучший способ — использовать .Destroy (). Существуют методы закрытия диалогового окна, например .Close (), который будет просто диалогом, но не уничтожит его, поэтому .Destroy () — наиболее эффективный вариант для предотвращения такой ситуации.

Теперь давайте обновим класс MP3Panel, начиная с .update_mp3_listing ():

 def update_mp3_listing (self, folder_path):
self.current_folder_path = путь_папки
self.list_ctrl.ClearAll ()

себя.list_ctrl.InsertColumn (0, 'Художник', ширина = 140)
self.list_ctrl.InsertColumn (1, 'Альбом', ширина = 140)
self.list_ctrl.InsertColumn (2, 'Заголовок', ширина = 200)
self.list_ctrl.InsertColumn (3, 'Год', ширина = 200)

mp3s = glob.glob (путь_папки + '/*.mp3')
mp3_objects = []
индекс = 0
для mp3 в mp3:
mp3_object = eyed3.load (mp3)
self.list_ctrl.InsertItem (индекс,
mp3_object.tag.artist)
self.list_ctrl.SetItem (индекс, 1,
mp3_object.tag.album)
self.list_ctrl.SetItem (индекс, 2,
mp3_object.tag.title)
mp3_objects.append (mp3_object)
self.row_obj_dict [индекс] = mp3_object
index + = 1 

В приведенном выше примере текущий каталог устанавливается в указанную папку, а элемент управления списком очищается. Элементы управления списком остаются актуальными и показывают файлы MP3, с которыми вы в настоящее время работаете. Затем папка берется, и модуль Python globmodule используется для поиска файлов MP3. Затем MP3-файлы зацикливаются и конвертируются в объекты eyed3.Это делается путем вызова .load () eyed3. После этого вы можете добавить исполнителя, альбом и название Mp3 в список управления, если у MP3 есть соответствующие теги.

.InsertItem () используется для добавления новой строки в элемент управления списком в первый раз, а SetItem () используется для добавления строк в последующие столбцы. Последний шаг — сохранить объект MP3 в словаре Python row_obj_dict.

Теперь, чтобы отредактировать теги MP3, вам необходимо обновить обработчик событий .on_edit ():

 def on_edit (self, event):
selection = self.list_ctrl.GetFocusedItem ()
если выбор> = 0:
mp3 = self.row_obj_dict [выбор]
        dlg = EditDialog (mp3)
        dlg.ShowModal ()
self.update_mp3_listing (self.current_folder_path)
        dlg.Destroy () 

Выбор пользователя осуществляется путем вызова элемента управления списком .GetFocusedItem (). Он вернет -1, если пользователь ничего не выберет в элементе управления списком. Однако, если вы хотите извлечь объект MP3 из словаря, пользователь должен что-то выбрать.Затем вы можете открыть диалоговое окно редактора тегов MP3, которое будет настраиваемым диалоговым окном.

Как и раньше, диалоговое окно отображается модально, затем последние две строки в .on_edit () будут выполнять то, что в конечном итоге отобразит информацию о текущем теге MP3.

Сводка

Подведем итог тому, что мы узнали в этой статье —

  • Установка wxPython и работа с виджетами wxPython
  • Обработка событий в wxPython
  • Сравнение абсолютного позиционирования с сайзерами
  • Создание скелета приложение и рабочее приложение

Главной особенностью графического интерфейса пользователя wxPython является его надежность и большой набор виджетов, которые можно использовать для создания кроссплатформенных приложений.Поскольку вы теперь узнали, как создать работающее приложение, то есть редактор тегов MP3, вы можете попробовать свои силы, чтобы улучшить это приложение до более красивого с множеством новых функций, или, возможно, вы можете создать свое собственное замечательное приложение. Чтобы получить больше информации о советах и ​​приемах Python, ознакомьтесь с нашим учебным курсом по Python и научитесь программировать на Python, присоединившись к сертификационному курсу Python.

wxWidgets: Обзор wxPython

Эта тема была написана Робином Данном, автором оболочки wxPython.

wxPython — это смесь классов GUI wxWidgets и языка программирования Python.

Python

Так что же такое Python? Посетите http://www.python.org, чтобы узнать больше, но вкратце Python — это интерпретируемый интерактивный объектно-ориентированный язык программирования. Его часто сравнивают с Tcl, Perl, Scheme или Java.

Python сочетает в себе замечательную мощность с очень понятным синтаксисом. В нем есть модули, классы, исключения, динамические типы данных очень высокого уровня и динамическая типизация.Есть интерфейсы для многих системных вызовов и библиотек, а новые встроенные модули легко писать на C или C ++. Python также можно использовать в качестве языка расширения для приложений, которым требуется программируемый интерфейс.

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

wxPython

wxPython — это пакет Python, который можно импортировать во время выполнения, который включает набор модулей Python и модуль расширения (собственный код). Он предоставляет серию классов Python, которые отражают (или затеняют) многие классы графического интерфейса wxWidgets.Этот модуль расширения пытается максимально точно отразить иерархию классов wxWidgets. Это означает, что в wxPython есть класс wxFrame, который выглядит, пахнет, имеет вкус и действует почти так же, как класс wxFrame в версии C ++.

wxPython очень универсален. Его можно использовать для создания автономных приложений с графическим интерфейсом пользователя или в ситуациях, когда Python встроен в приложение C ++ в качестве внутреннего языка сценариев или макроязыка.

В настоящее время wxPython доступен для платформ Win32, а набор инструментов GTK (wxGTK) доступен на большинстве платформ Unix / X-windows.Посетите веб-сайт wxPython http://wxPython.org/ для получения подробной информации о том, как заставить wxPython работать на вас.

Так зачем вам использовать wxPython вместо C ++ и wxWidgets? Лично я предпочитаю использовать Python для всего. Я использую C ++ только тогда, когда мне абсолютно необходимо повысить производительность алгоритма, и даже тогда я обычно кодирую его как модуль расширения и оставляю большую часть программы на Python.

Еще одна хорошая вещь, для которой можно использовать wxPython, — это быстрое прототипирование ваших приложений wxWidgets.В C ++ вы должны постоянно проходить цикл редактирование-компиляция-ссылка-запуск, что может занять довольно много времени. В Python это всего лишь цикл редактирования-выполнения. Вы можете легко создать приложение за несколько часов с Python, что обычно занимает несколько дней или больше с C ++. Преобразование приложения wxPython в приложение C ++ / wxWidgets должно быть простой задачей.

Существуют и другие решения с графическим интерфейсом для Python.

Tkinter

Tkinter — это де-факто стандартный графический интерфейс для Python.Он доступен почти на всех платформах, включая Python и Tcl / TK. Почему Tcl / Tk? Ну, потому что Tkinter — это просто оболочка для набора инструментов графического интерфейса Tcl, Tk. У этого есть свои плюсы и минусы …

Положительным моментом является то, что Tk — довольно универсальный набор инструментов. Его можно заставить делать много вещей в самых разных средах. Довольно легко создавать новые виджеты и взаимозаменяемо использовать их в своих программах.

Обратной стороной является Tcl. При использовании Tkinter у вас фактически работают два отдельных интерпретатора языка: интерпретатор Python и интерпретатор Tcl для графического интерфейса.Поскольку внутренность Tcl в основном связана с обработкой строк, она также довольно медленная. (Неплохо на быстром Pentium II, но вы действительно заметите разницу на более медленных машинах.)

Только в последней версии Tcl / Tk нативная функция Look and Feel стала возможной на платформах, отличных от Motif. Это связано с тем, что Tk обычно реализует свои собственные виджеты (элементы управления), даже если доступны собственные элементы управления.

Tkinter — довольно низкоуровневый инструментарий. Вам нужно проделать много работы (подробный программный код), чтобы делать то, что было бы намного проще с более высоким уровнем абстракции.

PythonWin

PythonWin — это дополнительный пакет для Python для платформы Win32. Он включает оболочки для MFC, а также большую часть Win32 API. Благодаря своей основе он хорошо знаком программистам, имеющим опыт работы с MFC и Win32 API. Очевидно, что он несовместим с другими платформами и инструментами. PythonWin организован в виде отдельных пакетов и модулей, поэтому вы можете использовать нужные вам части без необходимости использования частей графического интерфейса.

Другое

Для Python доступно довольно много других модулей графического интерфейса пользователя, некоторые из которых активно используются, а некоторые не обновлялись в течение долгого времени.Большинство из них являются простыми оболочками для какого-либо набора инструментов C или C ++ или другого, и большинство из них не совместимы с кросс-платформой. По этой ссылке вы найдете список некоторых из них.

Я не собираюсь здесь учить язык Python. Вы можете сделать это в Руководстве по Python. Я также предполагаю, что вы уже немного знаете о wxWidgets, достаточно, чтобы заметить сходство в используемых классах.

Взгляните на следующую программу wxPython. Вы можете найти аналогичную программу в каталоге wxPython / demo с именем DialogUnits.py . Если ваш Python и wxPython установлены правильно, вы сможете запустить его, введя следующую команду:

01: ## импортировать весь пакет графического интерфейса пользователя wxPython

02: из импорта wxPython.wx *

03:

04: ## Создайте новый класс фрейма, производный от фрейма wxPython.

05: класс MyFrame (wxFrame):

06:

07: def __init __ (я, родитель, идентификатор, заголовок):

08: # Сначала вызовите метод __init__ базового класса для создания кадра

09: wxFrame. __init __ (я, родитель, идентификатор, заголовок,

10: wxPoint (100, 100), wxSize (160, 100))

11:

12: # Свяжите некоторые события с методами этого класса

13: EVT_SIZE (self, self.OnSize)

14: EVT_MOVE (self, self.OnMove)

15:

16: # Добавить панель и некоторые элементы управления для отображения размера и положения

17: панель = wxPanel (self, -1)

18: wxStaticText (панель, -1, «Размер:»,

19: wxDLG_PNT (панель, wxPoint (4, 4)), wxDefaultSize)

20: wxStaticText (панель, -1, «Pos:»,

21: wxDLG_PNT (панель, wxPoint (4, 14)), wxDefaultSize)

22: сам.sizeCtrl = wxTextCtrl (панель, -1, «»,

23: wxDLG_PNT (панель, wxPoint (24, 4)),

24: wxDLG_SZE (панель, wxSize (36, -1)),

25: wxTE_READONLY)

26: self.posCtrl = wxTextCtrl (панель, -1, «»,

27: wxDLG_PNT (панель, wxPoint (24, 14)),

28: wxDLG_SZE (панель, wxSize (36, -1)),

29: wxTE_READONLY)

30:

31:

32: # Этот метод вызывается автоматически, когда событие CLOSE равно

33: # отправлено в это окно

34: def OnCloseWindow (себя, событие):

35: # скажем окну убить себя

36: сам.Уничтожить ()

37:

38: # Этот метод вызывается системой при изменении размера окна,

39: # из-за указанной выше связи.

40: def OnSize (себя, событие):

41: размер = event.GetSize ()

42: self.sizeCtrl.SetValue («% s,% s»% (size.width, size.height))

43:

44: # указать системе событий продолжить поиск обработчика событий,

45: # поэтому будет вызван обработчик по умолчанию.

46: event.Skip ()

47:

48: # Этот метод вызывается системой при перемещении окна,

49: # из-за указанной выше связи.

50: def OnMove (себя, событие):

51: pos = event.GetPosition ()

52: self.posCtrl. SetValue («% s,% s»% (pos.x, pos.y))

53:

54:

55: # Каждое приложение wxWidgets должно иметь класс, производный от wxApp

56: класс MyApp (wxApp):

57:

58: # wxWidgets вызывает этот метод для инициализации приложения

59: def OnInit (сам):

60:

61: # Создайте экземпляр нашего настроенного класса Frame

62: frame = MyFrame (NULL, -1, «Это тест»)

63: рамка.Показать (правда)

64:

67:

68: # Вернуть флаг успеха

69: вернуть истину

70:

71:

72: app = MyApp (0) # Создать экземпляр класса приложения

73: app.MainLoop () # Скажите ему начать обработку событий

74:

На заметку

В строке 2 классы, константы и т. Д. WxPython импортируются в пространство имен текущего модуля. Если вы предпочитаете уменьшить загрязнение пространства имен, вы можете использовать "из wxPython import wx" , а затем получить доступ ко всем идентификаторам wxPython через модуль wx, например, "wx.wxFrame ".

В строке 13 события изменения размера и перемещения кадра связаны с методами класса. Эти вспомогательные функции должны напоминать макросы таблицы событий, которые использует wxWidgets. Но поскольку статические таблицы событий невозможны с wxPython, мы используем помощники с одинаковыми именами для динамического построения таблицы. Единственное реальное отличие состоит в том, что первым аргументом помощников по событиям всегда является окно, в которое должна быть добавлена ​​запись в таблице событий.

Обратите внимание на использование wxDLG_PNT и wxDLG_SZE в строках 19–29 для преобразования единиц диалогового окна в пиксели.Эти помощники уникальны для wxPython, поскольку Python не может выполнять перегрузку методов, как C ++.

В строке 34 есть метод OnCloseWindow , но нет вызова EVT_CLOSE для присоединения события к методу. Это действительно называется? Ответ — да. Это связано с тем, что многие стандартные события привязаны к окнам, которые имеют соответствующие имена стандартных методов. Я попытался последовать примеру классов C ++ в этой области, чтобы определить, что является стандартным, но, поскольку это время от времени меняется, я не могу дать никаких гарантий, и это не будет полностью задокументировано.В случае сомнений используйте функцию EVT _ *** .

В строках с 17 по 21 обратите внимание на отсутствие сохраненных ссылок на панель или созданные статические текстовые элементы. Тем из вас, кто знаком с Python, может быть интересно, что происходит, когда Python удаляет эти объекты, когда они выходят за пределы области видимости. Они исчезают из графического интерфейса? Они этого не делают. Помните, что в wxPython объекты Python — это просто тени соответствующих объектов C ++. После того, как окна и элементы управления C ++ прикреплены к их родителям, родители управляют ими и при необходимости удаляют их.По этой причине большинству объектов wxPython не нужен метод del , который явно вызывает удаление объекта C ++. Если вам когда-либо понадобится принудительно удалить окно, используйте метод Destroy (), как показано в строке 36.

Как и wxWidgets в C ++, приложениям wxPython необходимо создать класс, производный от wxApp (строка 56), который реализует метод с именем OnInit , (строка 59). Этот метод должен создать главное окно приложения (строка 62) и покажи это.

И, наконец, в строке 72 создается экземпляр класса приложения. На этом этапе wxPython завершает инициализацию и вызывает метод OnInit , чтобы начать работу. (Нулевой параметр здесь — это флаг функциональности, которая еще не реализована. Просто проигнорируйте его пока.) Вызов MainLoop в строке 73 запускает цикл событий, который продолжается до завершения приложения или всех окон верхнего уровня. закрыты.

В wxPython поддерживаются следующие классы.Большинство из них предоставляют почти полную реализацию общедоступных интерфейсов, указанных в документации C ++, другие — в меньшей степени. Со временем все они будут максимально приближены к спецификации C ++.

Поскольку wxPython представляет собой сочетание нескольких технологий, помощь приходит из нескольких источников. См. Http://wxpython.org/ для получения подробной информации о различных источниках помощи, но, вероятно, лучшим источником является список рассылки пользователей wxPython. Вы можете просмотреть архив или подписаться на http://wxpython.org/maillist.php

Или вы можете отправить письмо прямо в список, используя этот адрес: wxpyt [защита электронной почты] hon- [защита электронной почты] пользователи [защита электронной почты] @lis [защита электронной почты] ts.wx [защита электронной почты] widg [защита электронной почты] ets. o [адрес электронной почты защищен] rg

Создание приложений Python с графическим интерфейсом пользователя с помощью wxPython

Введение

В этом руководстве мы узнаем, как использовать библиотеку wxPython для разработки графических пользовательских интерфейсов (GUI) для настольных приложений на Python. GUI — это часть вашего приложения, которая позволяет пользователю взаимодействовать с вашим приложением без необходимости вводить команды, они могут делать практически все одним щелчком мыши.

Некоторые из популярных альтернатив Python для разработки графического интерфейса пользователя включают Tkinter и pyqt. Однако в этом руководстве мы узнаем о wxPython.

Прежде чем мы двинемся дальше, есть несколько предварительных условий для этого руководства. Вы должны иметь базовое представление о синтаксисе Python и / или программировать на каком-либо другом языке, по крайней мере, для начинающих. Хотя вы можете следовать ему, даже если вы не соответствуете этим критериям, но некоторые части могут оказаться для вас немного сложными. Если да, не стесняйтесь спрашивать разъяснения в комментариях.

Установка

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

Mac и Windows

WxPython довольно легко установить на Mac и Windows с помощью диспетчера пакетов pip. Если в вашей системе установлен pip, выполните следующую команду для загрузки и установки wxPython:

  $ pip install wxpython
  
Linux

Для Linux процедура может быть немного неудобной, так как она требует установки множества необходимых библиотек.Я бы порекомендовал попробовать последовательно выполнить следующие две команды:

  # Команда 1
$ sudo apt-get install dpkg-dev build-essential python2.7-dev python3.5-dev python3.6-dev libgstreamer-plugins-base1.0-dev libnotify-dev libwebkitgtk-3.0-dev libwebkit-dev libwebkitgtk-dev libjpeg-dev libtiff-dev libgtk2.0-dev libsdl1.2-dev libgstreamer-plugins-base0.10-dev freeglut3 freeglut3-dev

# Команда 2
$ pip install --upgrade --pre -f https://wxpython.org/Phoenix/snapshot-builds/ wxPython
  

Однако, если они не работают, вам придется вручную установить эти библиотеки, список которых указан в разделе «Предварительные требования» репозитория WxPython на Github.

Примеры создания графического интерфейса пользователя с помощью wxPython

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

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

Без лишних слов, приступим. Ниже приведен базовый скелет или структура приложения с графическим интерфейсом, созданного с использованием wxPython. Мы изменим его дальше в следующем разделе, чтобы сделать его объектно-ориентированным для дополнительной функциональности.

  импорт wx

# Создает объект App, который запускает цикл для отображения
# GUI на экране
myapp = wx.App ()

# Инициализирует фрейм, который пользователь сможет
# взаимодействовать с
init_frame = wx.Frame (parent = None, title = 'Word Play')

# Отображение инициализированного кадра на экране
init_frame.Шоу()

# Запускаем цикл на объекте приложения
myapp.MainLoop ()
  

Если цикл не запущен (т.е. вызов app.MainLoop () ), то кадр появится на экране на долю секунды, и даже прежде, чем вы сможете его увидеть, он исчезнет. Эта функция гарантирует, что кадр остается видимым на экране до тех пор, пока пользователь не выйдет из программы, и делает это путем запуска кадра в цикле.

Примечание : при запуске этого на Mac я получил следующую ошибку, когда я запустил свой код с использованием имени файла python.py команда в терминале:

  Этой программе нужен доступ к экрану. Пожалуйста, запускайте со сборкой Python на платформе Framework, и только когда вы вошли в систему на основном дисплее вашего Mac.
  

Чтобы избавиться от этого, просто используйте pythonw вместо python в приведенной выше команде.

После запуска программы вы должны увидеть на экране следующее пустое окно:

Объектно-ориентированный код

Прежде чем добавлять функциональные возможности в наш код, давайте сначала разберем его на модули, создав классы и функции, чтобы он выглядел чище и его было легче расширять.Функциональность следующего кода такая же, как и раньше, однако он был переработан для реализации концепций объектно-ориентированного программирования.

  импорт wx
оператор импорта

# Делаем класс для фрейма, чтобы каждый раз
# создать новый фрейм, мы можем просто создать новый
# объект для этого

класс WordPlay (wx. Frame):
    def __init __ (я, родитель, заголовок):
        super (WordPlay, self) .__ init __ (родительский, title = title)
        self.Show ()

def main ():
    myapp = wx.App ()
    WordPlay (Нет, title = 'Word Play')
    myapp.MainLoop ()

основной()
  

В приведенном выше сценарии мы создаем класс WordPlay , который наследует класс wxFrame . Конструктор класса WordPlay принимает два параметра: родительский и заголовок . Внутри дочернего конструктора вызывается конструктор родительского класса для класса wxPython , и ему передаются атрибуты parent и title . Наконец, для отображения кадра вызывается метод show .В методе main () создается объект класса WordPlay .

Код теперь выглядит более структурированным и чистым; его легче понять, и в приведенный выше код можно легко добавить больше функций.

Добавление функций

Мы будем добавлять функциональные возможности по одной, чтобы избежать путаницы в отношении того, какая часть кода добавляется для какой конкретной функции. В нашем базовом приложении нам нужно текстовое поле, в которое мы можем добавить текст, а затем несколько кнопок для выполнения различных функций с этим текстом, таких как вычисление количества слов в нем, частоты каждого слова и т. Д., за которым следует вывод, отображаемый на экране нашего приложения.

Начнем с добавления текстового поля в наше приложение, в которое мы можем добавить наш текст.

  # Часть кода будет такая же, как и выше,
# поэтому убедитесь, что вы понимаете это, прежде чем переходить
# к этой части

импорт wx
оператор импорта

# Мы создаем класс для фрейма, чтобы каждый раз, когда мы создаем новый фрейм,
# мы можем просто создать для него новый объект

класс WordPlay (wx.Frame):
    def __init __ (я, родитель, заголовок):
        супер (WordPlay, сам).__init __ (родитель, заголовок = заголовок)
        self. widgets ()
        self.Show ()

    # Объявить функцию для добавления новых кнопок, значков и т. Д. В наше приложение
    def виджеты (себя):
        text_box = wx.BoxSizer (wx.VERTICAL) # Вертикальная ориентация

        self.textbox = wx.TextCtrl (self, style = wx.TE_RIGHT)
        text_box.Add (self.textbox, flag = wx.EXPAND | wx.TOP | wx.BOTTOM, border = 5)

        grid = wx.GridSizer (5, 5, 10, 10) # Строки, столбцы, вертикальный зазор, горизонтальный зазор
        text_box.Add (сетка, пропорция = 2, flag = wx.РАСШИРЯТЬ)

        self.SetSizer (текстовое поле)

def main ():
    myapp = wx.App ()
    WordPlay (Нет, title = 'Word Play')
    myapp.MainLoop ()

основной()
  

Как видите, мы добавили новую функцию с именем widgets () выше, и она была вызвана в конструкторе класса WordPlay . Его цель — добавить новые виджеты на наш экран; однако в нашем случае нас интересует только добавление одного виджета, то есть текстового поля, в которое мы можем добавить некоторый текст.

Давайте теперь разберемся с некоторыми важными вещами, которые происходят внутри функции widgets () .Метод BoxSizer () , как следует из названия, управляет размером виджета, а также его положением (относительным или абсолютным). wx.VERTICAL указывает, что нам нужна вертикальная ориентация для этого виджета. TextCtrl в основном добавляет небольшое текстовое поле в наш текущий объект from, где пользователь может вводить текст. Метод GridSizer () помогает нам создать табличную структуру для нашего окна.

Хорошо, давайте теперь посмотрим, как выглядит наше приложение.

Текстовое поле теперь можно увидеть в окне нашего приложения.

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

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

  # Добавление кнопок в наше главное окно

def виджеты (себя):
    text_box = wx.BoxSizer (wx.VERTICAL)

    self.textbox = wx.TextCtrl (self, style = wx.TE_RIGHT)
    text_box.Add (self.textbox, flag = wx.EXPAND | wx.TOP | wx.BOTTOM, border = 5)

    сетка = wx.GridSizer (2, 5, 5) # Значения изменены для корректировки положения кнопок
    button_list = ['Подсчет слов', 'Наиболее часто повторяющееся слово'] # Список меток кнопок

    для лаборатории в button_list:
        button = wx.Button (self, -1, lab) # Инициализировать объект кнопки
        grid.Add (button, 0, wx.EXPAND) # Добавляем новую кнопку в сетку с меткой из button_list

    text_box.Add (сетка, пропорция = 2, флаг = wx.EXPAND)

    self.SetSizer (текстовое поле)
  

Как видите, к нашему главному окну теперь добавлены две новые кнопки.

Добавление обработчика событий

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

  # Объявить функцию обработчика событий

def event_handler (себя, событие):
    # Получить метку нажатой кнопки
    btn_label = event.GetEventObject (). GetLabel ()

    # Получить текст, введенный пользователем
    text_entered = сам.текстовое поле.GetValue ()

    # Разбиваем предложение на слова
    words_list = text_entered.split ()

    # Выполнять разные действия на основе разных нажатий кнопок
    если btn_label == "Считать слова":
        результат = len (список_слов)
    elif btn_label == "Самое повторяющееся слово":
        # Объявить пустой словарь для хранения всех слов и
        # сколько раз они встречаются в тексте
        word_dict = {}

        на слово в words_list:
            # Отслеживаем количество каждого слова в нашем dict
            если слово в word_dict:
                word_dict [слово] + = 1
            еще:
                word_dict [слово] = 1

            # Сортировка слов в порядке убывания, чтобы
            # самое повторяющееся слово вверху
            sorted_dict = отсортировано (word_dict. Предметы(),
                                key = operator.itemgetter (1),
                                reverse = True)

            # Первым значением в слове будет самое повторяющееся слово
            результат = sorted_dict [0]

    # Установите значение текстового поля как результат наших вычислений
    self.textbox.SetValue (str (результат))
  

Логика, лежащая в основе функции «Наиболее часто повторяющееся слово», заключается в том, что мы сначала запускаем цикл, который выполняет итерацию по слову из списка всех слов. Затем он проверяет, существует ли это конкретное слово уже в словаре; если это так, то это означает, что оно повторяется, и его значение увеличивается на единицу каждый раз, когда слово появляется снова.В противном случае, если он не существует в словаре, это означает, что он появился в предложении впервые, и его значение «вхождения» должно быть установлено на 1. Наконец, мы сортируем словарь (аналогично сортировке списка в Python. ) в порядке убывания, чтобы слово с наивысшим значением (частотой) выходило на первое место, которое мы затем можем отобразить.

Хорошо, теперь, когда мы написали вычисление / действие, которое должно выполняться при нажатии определенной кнопки, давайте «привяжем» это действие к этой конкретной кнопке.Для этого нам нужно немного изменить функцию виджетов .

  # Только одна строка должна быть добавлена ​​в "цикл for"
# наши виджеты работают, так что это все, что мы показываем
для лаборатории в button_list:
    button = wx.Button (self, -1, lab)
    self.Bind (wx.EVT_BUTTON, self.event_handler, кнопка)
    grid.Add (кнопка, 0, wx.EXPAND)
  

В приведенном выше коде выполняется привязка self.Bind . Что он делает, так это то, что он связывает определенное действие с определенной кнопкой, так что, когда вы нажимаете эту кнопку, будет выполнено определенное действие, связанное с ней.В нашем конкретном случае у нас есть только одна функция обработчика событий, которая обрабатывает оба действия, проверяя во время выполнения, какая кнопка была нажата через свойство 'label', а затем выполняет связанное действие. Итак, в вызове self.Bind мы привязываем все наши кнопки к одной функции event_handler.

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

На первом этапе, как показано ниже, мы вводим строку в текстовое поле:

Затем, если мы нажмем кнопку «Подсчитать слова», вы увидите цифру «7» в текстовом поле, поскольку в строке было 7 слов.

Пока все хорошо!

Теперь давайте напишем еще одну строку в текстовое поле, как показано на следующем рисунке:

Теперь, если мы нажмем кнопку «Наиболее часто повторяющееся слово», вы увидите наиболее часто повторяющиеся слова в текстовом поле вместе с частотой их появления, как показано ниже:

Работает отлично!

Мы добавили только две функции, но цель заключалась в том, чтобы показать вам, как все эти компоненты связаны между собой. Вы можете добавить столько функций, сколько захотите, просто написав для них дополнительные функции.Кроме того, в этом уроке не уделялось особого внимания эстетике. В wxPython доступно множество виджетов, чтобы украсить вашу программу теперь, когда вы усвоили базовые знания этого инструментария.

Заключение

Подводя итог, мы узнали, что wxPython широко используется для разработки настольных приложений на основе графического интерфейса пользователя на Python, и что у Python также есть несколько других интересных альтернатив для него. Мы прошли через команды, чтобы загрузить и установить его во всех популярных операционных системах.Наконец, мы узнали, как создать модульное приложение с помощью wxPython, которое можно легко расширить, как можно увидеть в этом руководстве, где мы создали базовое приложение-скелет и добавили дополнительные функции шаг за шагом.

Тест-драйв графического интерфейса пользователя

Python: wxPython против PyQt

Python - популярный язык, способный создавать сценарии, а также объектно-ориентированное программирование. Несколько фреймворков предоставляют GUI (графический пользовательский интерфейс) для Python, и большинство из них хороши в чем-то, будь то простота, эффективность или гибкость.Двумя наиболее популярными из них являются wxPython и PyQt, но как они сравниваются? Что еще более важно, что выбрать для своего проекта?

Внешний вид

Давайте разберемся, что в первую очередь замечает большинство пользователей - как выглядит приложение.

Одной из уникальных особенностей wxPython является то, что его основные библиотеки, написанные на C ++, являются оболочкой для собственных виджетов хост-системы. Когда вы пишете код для виджета-кнопки в своем графическом интерфейсе, вы не получаете ничего, что выглядело бы так, как будто оно принадлежит другой операционной системе, и не получаете простого приближения.Скорее, вы получите тот же объект, что и при написании кода с помощью собственных инструментов.

Thunar и WxPython в Linux

Это отличается от PyQt, который основан на знаменитом наборе инструментов Qt. PyQt также написан на C ++, но он не использует собственные виджеты, а вместо этого создает приближения виджетов в зависимости от того, какую ОС он обнаруживает. Это дает хорошее приближение, и у меня никогда не было пользователя - даже в художественной школе, где пользователи, как правило, печально известны педантизмом в отношении внешнего вида - жаловались, что приложение не выглядело и не чувствовалось родным.

Если вы используете KDE, у вас есть дополнительные библиотеки PyKDE, доступные для преодоления разрыва между необработанным PyQt и внешним видом вашего рабочего стола Plasma в Linux и BSD, но это добавляет новые зависимости.

KDE и Qt в Linux

Кроссплатформенный

Как wxPython, так и PyQt поддерживают Linux, Windows и Mac, поэтому они идеально подходят для знаменитого кроссплатформенного Python; однако не позволяйте термину «кроссплатформенность» вводить вас в заблуждение - вы все равно должны вносить в код Python специфические настройки. Ваш набор инструментов GUI не может настраивать форматы путей к каталогам данных, поэтому вам все равно придется применять передовые практики в Python, используя os.path.join и несколько различных методов exit и т. Д. Выбранный вами инструментарий графического интерфейса не будет волшебным образом абстрагироваться от платформы к платформе.

PyQt работает, чтобы оградить вас от различий кросс-платформенных. Допуская общие настройки, которые требует сам Python, PyQt изолирует вас от большинства кроссплатформенных проблем, так что ваш код графического интерфейса остается неизменным независимо от ОС.Всегда есть исключения, но PyQt отлично справляется с этим. Это роскошь, которой вы будете ценить и восхищаться ею.

В wxPython вам может потребоваться внести некоторые изменения в код графического интерфейса, зависящие от платформы, в зависимости от того, что вы программируете. Например, чтобы предотвратить мерцание некоторых элементов в Microsoft Windows, атрибут USE_BUFFERED_DC должен иметь значение True для двойной буферизации графики. Это не по умолчанию, хотя это можно сделать безоговорочно для всех платформ, поэтому в некоторых случаях использования у него могут быть недостатки, но это хороший пример допущений, которые вы должны сделать для wxPython.

Установить

Как разработчик, вы, вероятно, не возражаете против этапов установки, необходимых для получения библиотек, необходимых для вашего приложения; однако, если вы планируете распространять свое приложение, вам необходимо принять во внимание процесс установки, который должны пройти ваши пользователи, чтобы ваше приложение заработало.

Установить Qt на любую платформу так же просто, как установить любое другое приложение :. Дайте пользователям ссылку для загрузки, скажите им установить загруженный пакет, и они сразу же начнут использовать ваше приложение.Это верно для всех поддерживаемых платформ.

Что также верно для всех платформ, так это то, что PyQt зависит от кода C ++ самого Qt. Это означает, что пользователям необходимо установить не только PyQt, но и весь Qt. Это не маленький пакет, и в нем много щелчков и, возможно, пошаговых мастеров установки. Команды Qt и PyQt делают установку настолько простой, насколько это возможно, поэтому, хотя может показаться, что спрашивать пользователя слишком много, если вы предоставляете прямые ссылки, любой пользователь, который может установить веб-браузер или игру должен иметь возможность бороться с установкой Qt.Если вы очень преданы своему делу, вы можете даже создать сценарий установки как часть вашего собственного установщика.

В Linux, BSD и семействе Ilumos установка обычно уже написана за вас менеджером пакетов дистрибутива.

Процесс установки wxPython так же прост в Linux и Windows, но проблематичен в Mac OS. Загружаемые пакеты сильно устарели, что является еще одной жертвой незаинтересованности Apple в обратной совместимости. Существует сообщение об ошибке с исправлением, но пакеты не обновлялись, поэтому шансы, что среднестатистические пользователи сами найдут и внедряют исправление, невелики.Решение прямо сейчас состоит в том, чтобы упаковать wxPython и распространить его среди пользователей Mac OS самостоятельно или полагаться на внешний менеджер пакетов (хотя, когда я последний раз тестировал wxPython для Mac, даже эти сценарии установки не удались).

Виджеты и функции

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

PyQt имеет преимущество гибкости. Вы можете переупорядочивать, перемещать, закрывать и восстанавливать панели Qt во время выполнения, предоставляя каждому приложению настраиваемый интерфейс, ориентированный на удобство использования.

Перемещение панелей Qt

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

WxPython имеет множество замечательных функций, но он не может сравниться с PyQt с точки зрения гибкости и пользовательского контроля.С одной стороны, это означает, что проектирование и верстка упрощаются для вас как разработчика. При разработке на Qt не требуется много времени, прежде чем вы получите запросы от пользователей о способах отслеживания пользовательских макетов или о том, как найти потерянную панель, которая случайно закрылась, и так далее. По той же причине wxPython проще для ваших пользователей, поскольку потерять панель, которая была случайно закрыта, намного сложнее, когда панели не могут быть закрыты вообще.

В конце концов, wxPython - это всего лишь интерфейс для wxWidgets, поэтому, если вам действительно нужна функция, вы можете реализовать ее на C ++, а затем использовать в wxPython.Однако по сравнению с PyQt это сложная задача.

Шкивы и шестерни

Приложение с графическим интерфейсом состоит из множества более мелких визуальных элементов, обычно называемых «виджетами». Чтобы приложение с графическим интерфейсом пользователя работало без сбоев, виджеты должны взаимодействовать друг с другом, чтобы, например, панель, предназначенная для отображения изображения, знала, какой эскиз выбрал пользователь.

Большинство наборов инструментов GUI, включая wxPython, имеют дело с внутренним обменом данными с помощью «обратных вызовов». Обратный вызов - это указатель на некоторый фрагмент кода («функцию»).Если вы хотите, чтобы что-то происходило при нажатии, например, виджета-кнопки, вы пишете функцию для действия, которое вы хотите выполнить. Затем, когда кнопка нажата, вы вызываете функцию в своем коде, и действие происходит.

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

Qt, с другой стороны, известен своим механизмом «сигналов и слотов».Если вы представляете внутреннюю коммуникационную сеть wxPython как телефонный коммутатор старого образца, тогда представьте себе связь PyQt как ячеистую сеть.

Сигналы и слоты в Qt (лицензия GFDL на диаграмму Qt)

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

Слоты

могут быть настроены на прослушивание любого количества сигналов, а сигналы могут быть настроены на широковещательную передачу на любое количество слотов. Вы даже можете соединить сигнал с другим сигналом, чтобы создать цепную реакцию сигналов. Вам никогда не придется возвращаться в свой код, чтобы «связать» все вместе вручную.

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

Более того, слоты - это не просто слушатели; это обычные функции, которые могут делать полезные вещи с сигналом или без него.Так же, как объект не знает, слушает ли что-нибудь его сигнал, слот не знает, слушает ли он сигнал. Ни один блок кода никогда не зависит от существующего соединения; он просто запускается в разное время, если есть соединение.

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

Макет

Когда вы программируете приложение с графическим интерфейсом, вы должны разработать его макет так, чтобы все виджеты знали, где появиться в окне вашего приложения. Как и веб-страница, вы можете выбрать дизайн приложения с изменяемым размером или ограничить его фиксированным размером. В некотором смысле, это самая важная часть графического интерфейса программирования.

В Qt все довольно логично. Виджеты имеют разумные названия ( QPushButton , QDial , QCheckbox , QLabel и даже QCalendarWidget ) и их легко вызвать. Документация отличная, если вы часто к ней возвращаетесь, и обнаруживать в ней интересные функции легко.

Есть потенциальные точки путаницы, в основном в элементах графического интерфейса базового уровня. Например, если вы пишете приложение, начинаете ли вы с QMainWindow или QWidget для формирования родительского окна? Оба могут служить окном для вашего приложения, поэтому ответ, как это часто бывает в вычислительной технике: это зависит от обстоятельств.

QWidget - это необработанный пустой контейнер. Он используется всеми другими виджетами, но это означает, что он также может использоваться как есть для формирования родительского окна, в которое вы помещаете дополнительные виджеты. QMainWindow , как и все другие виджеты, использует QWidget , но добавляет множество удобных функций, которые необходимы большинству приложений, например панель инструментов вверху, строка состояния внизу и т. Д.

QMainwindow

Небольшой текстовый редактор, использующий QMainWindow чуть более чем в 100 строках кода Python:

#! / usr / bin / env python 
# минимальный текстовый редактор для демонстрации PyQt5

# Полная лицензия GNU
# Копирование и распространение этого файла с модификациями или без них,
# разрешены на любом носителе без лицензионных отчислений при условии соблюдения уведомление об авторском праве
# и это уведомление сохранены. Этот файл предлагается как есть,
#, без каких-либо гарантий.

import sys
import os
import pickle
from PyQt5 import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class TextEdit (Q931__ defindow):
class TextEdit (Q931__ defindow): :
super (TextEdit, self) .__ init __ ()
#font = QFont ("Courier", 11)
# self.setFont (font)
self.filename = False
self.Ui ()

def Ui (self ):
quitApp = QAction (QIcon ('/ usr / share / icons / breeze-dark / actions / 32 / application-exit.svg '),' Quit ', self)
saveFile = QAction (QIcon (' / usr / share / icons / breeze-dark / actions / 32 / document-save.svg '),' Save ', self)
newFile = QAction ('New', self)
openFile = QAction ('Open', self)
copyText = QAction ('Copy', self)
pasteText = QAction ('Yank', self)
newFile.setShortcut ('Ctrl + N ')
newFile.triggered.connect (self.newFile)
openFile.setShortcut (' Ctrl + O ')
openFile.triggered.connect (self.openFile)
saveFile.setShortcut ('Ctrl + S')
saveFile.triggered.connect (self.saveFile)
quitApp.setShortcut ('Ctrl + Q')
quitApp.triggered.connect (self.close)
copyText.setShortcut ('Ctrl + K ')
copyText.triggered.connect (self.copyFunc)
pasteText.setShortcut (' Ctrl + Y ')
pasteText.triggered.connect (self.pasteFunc)
menubar = self.menuBar ()
menubar.setNativeMenu
menuFile = menubar.addMenu ('& File')
menuFile.addAction (newFile)
menuFile.addAction (openFile)
menuFile.addAction (saveFile)
menuFile.addAction (quitApp)
menuEdit = menubar.addMenu ('& Edit')
menuEdit.addAction (copyText)
T menuEdit. 'Toolbar')
toolbar.addAction (quitApp)
toolbar.addAction (saveFile)
self.text = QTextEdit (self)
self.setCentralWidget (self.text)
self.setMenuWidget (menubar)
self. setMenuBar (menuBar)
сам.setGeometry (200,200,480,320)
self.setWindowTitle ('TextEdit')
self.show ()

def copyFunc (self):
self.text.copy ()

def pasteFunc (self):
self.text.paste ( )

def unSaved (self):
destroy = self.text.document (). IsModified ()
print (destroy)

if destroy == False:
return False
else:
detour = QMessageBox.question (self ,
"Держите лошадей.",
" В файле есть несохраненные изменения. Сохранить сейчас? ",
QMessageBox.Yes | QMessageBox.No |
QMessageBox.Cancel)
if detour == QMessageBox.Cancel:
return True
elif detour == QMessageBox.No:
return detage
elif. Да:
return self.saveFile ()

return True

def saveFile (self):
self.filename = QFileDialog.getSaveFileName (self, 'Сохранить файл', os.path.expanduser ('~'))
f = self.filename [0]
с open (f, "w") как CurrentFile:
CurrentFile.write (self.text.toPlainText ())
CurrentFile.close ()

def newFile (self):
, если не self.unSaved ():
self.text.clear ()

def openFile (self):
имя файла , _ = QFileDialog.getOpenFileName (self, «Открыть файл», '', «Все файлы (*)»)
try:
self.text.setText (open (filename) .read ())
except:
True

def closeEvent (self, event):
if self.unSaved ():
event.ignore ()
else:
exit

def main ():
app = QApplication (sys.argv)
editor = TextEdit ()
sys.exit (app.exec_ ())

if __name__ == '__main__':
main ()

Основным виджетом в wxPython является wx.Window . Все в wxPython, будь то фактическое окно или просто кнопка, флажок или текстовая метка, основано на wx.Окно кл. Если бы были награды за наиболее ошибочно названный класс, wx.Window не принимали бы во внимание, потому что это , так что плохо назван, чтобы никто не заподозрил его в неправильности. Мне сказали, что привыкание к wx.Window , не являющемуся окном, занимает годы, и это должно быть правдой, потому что я делаю эту ошибку каждый раз, когда использую его.

Класс wx.Frame играет традиционную роль того, что мы с вами воспринимаем как окно на рабочем столе. Использовать wx.Рамка для создания пустого окна:

#! / usr / bin / env python 
# - * - coding: utf-8 - * -

import wx

class Myframe (wx.Frame):

def __init __ (self, parent, title):
super ( Myframe, self) .__ init __ (parent, title = title,
size = (520, 340))
self.Centre ()
self.Show ()

if __name__ == '__main__':
app = wx.App ()
Myframe (None, title = 'Просто пустой фрейм')
app.MainLoop ()

Поместите другие виджеты в окно wx.Frame , а затем вы создадите приложение с графическим интерфейсом. Например, виджет wx.Panel похож на div в HTML с ограничениями абсолютного размера, поэтому вы можете использовать его для создания панелей в главном окне (за исключением того, что это не окно, это wx.Frame ). ).

WxPython имеет меньше удобных функций по сравнению с PyQt. Например, функция копирования и вставки встроена прямо в PyQt, тогда как ее нужно кодировать вручную в wxPython (и все еще частично зависит от платформы, на которой он работает).Некоторые из них любезно обрабатываются хорошим рабочим столом со встроенными функциями, но для обеспечения паритета функций с приложением PyQt wxPython требует немного больше ручной работы.

ш. Рама

Простой текстовый редактор в wxPython:

#! / usr / bin / env python 
# минимальный текстовый редактор для демонстрации wxPython

# Полностью разрешенная лицензия GNU
# Копирование и распространение этого файла с модификациями или без них,
# разрешены на любом носителе без лицензионных отчислений при условии, что уведомление об авторском праве
# и это уведомление сохранены. Этот файл предлагается как есть,
#, без каких-либо гарантий.

import wx
import os

class TextEdit (wx.Frame):
def __init __ (self, parent, title):
wx.Frame .__ init __ (self, parent, wx.ID_ANY, title, size = (520, 340))
menuBar = wx.MenuBar ()
menuFile = wx.Menu ()
menuBar.Append (menuFile, "& File")
menuFile.Append (1, "& Открыть")
menuFile.Append (2, "& Сохранить ")
menuFile.Append (3," & Quit ")
self.SetMenuBar (menuBar)
wx.EVT_MENU (self, 1, self.openAction)
wx.EVT_MENU (self, 2, self.saveAction)
wx.EVT_MENU (self, 3, self.quitAction)
self.p1 = wx. Panel (self)
self.initUI ()

def initUI (self):
self.text = wx.TextCtrl (self.p1, style = wx.TE_MULTILINE)
vbox = wx.BoxSizer (wx.VERTICAL)
vbox .Add (self.p1, 1, wx.EXPAND | wx.ALIGN_CENTER)
self.SetSizer (vbox)
self.Bind (wx.EVT_SIZE, self._onSize)
self.Show ()

def _onSize (self, e):
e.Skip ()
self.text.SetSize (self.GetClientSizeTuple ())

def quitAction (self, e):
если self.text.IsModified ( ):
dlg = wx.MessageDialog (self, «Выйти? Все изменения будут потеряны.», «», Wx.YES_NO)
, если dlg.ShowModal () == wx.ID_YES:
self.Close (True)
else:
self.saveAction (self)
else:
exit ()

def openAction (self, e):
dlg = wx.FileDialog (self, «Выбор файла», os.path.expanduser ('~'), «», «*. *», Wx.OPEN)
, если dlg.ShowModal () == wx.ID_OK:
filename = dlg .GetFilename ()
dir = dlg.GetDirectory ()
f = open (os.path.join (dir, filename), 'r')
self.text.SetValue (f.read ())
f.close ( )
dlg.Destroy ()

def saveAction (self, e):
dlg = wx.FileDialog (self, «Сохранить как», os.path.expanduser ('~'), «», «*. *» , wx.SAVE | wx.OVERWRITE_PROMPT)
если dlg.ShowModal () == wx.ID_OK:
filedata = self.text.GetValue ()
filename = dlg. GetFilename ()
dir = dlg.GetDirectory ()
f = open (os.path.join (dir, filename) , 'w')
f.write (filedata)
f.close ()
dlg.Destroy ()

def main ():
app = wx.App (False)
view = TextEdit (None, "TextEdit" )
app.MainLoop ()

if __name__ == '__main__':
main ()

Какой из них использовать?

У инструментов GUI PyQt и wxPython есть свои сильные стороны.

WxPython в основном прост, а когда он непростой, он интуитивно понятен программисту на Python, который не боится вместе взламывать решение. Вы не найдете много примеров «пути wxWidget», в который вас нужно внушать. Это набор инструментов, который вы можете использовать для создания графического интерфейса. Если вы ориентируетесь на пользовательское пространство, в котором, как вы знаете, уже установлен GTK, тогда wxPython подключается к нему с минимальными зависимостями.

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

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

PyQt большой и почти всегда требует установки нескольких зависимостей (особенно для целей, отличных от Linux и BSD). Наряду со всем этим объемным кодом приходит много удобства. Qt делает все возможное, чтобы защитить вас от различий в платформах; он предоставляет вам ошеломляющее количество готовых функций, виджетов и абстракций.Он хорошо поддерживается, и многие компании полагаются на него как на основную структуру, а некоторые из наиболее значительных проектов с открытым исходным кодом используют его и вносят свой вклад в его развитие.

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

Удачного взлома.

Python | Модуль wxPython Введение

Python | Модуль wxPython Введение

Python предоставляет модуль wxpython , который позволяет нам создавать высокофункциональный графический пользовательский интерфейс. Это модуль с открытым исходным кодом, что означает, что его может использовать любой, а исходный код доступен для просмотра и изменения.
Он реализован в виде набора модулей расширения, которые обертывают компоненты графического интерфейса библиотеки wxWidgets , написанной на C ++.Это кроссплатформенный набор инструментов с графическим интерфейсом для python, версия Phoenix Phoenix - это улучшенный wxPython следующего поколения, который в основном ориентирован на скорость, удобство обслуживания и расширяемость.

Установите с помощью этой команды:

 pip install wxpython 

Создание графического интерфейса с использованием wxpython:

  1. Сначала импортируйте модуль wx .
  2. Создайте объект для класса приложения.
  3. Создайте объект для класса фрейма, и другие элементы управления добавляются к объекту фрейма, поэтому его макет сохраняется с помощью панели.
  4. Затем добавьте статический текстовый объект, чтобы отобразить Hello World.
  5. Показать окно фрейма с помощью метода show.
  6. Запустите приложение, пока окно не закроется, используя объект приложения основного цикла событий.

Пример № 1: Простое приложение с графическим пользовательским интерфейсом, которое сообщает GEEKS FOR GEEKS с использованием wxpython.

импорт wx

app1 = wx.Приложение ()

рамка = wx.Frame ( Нет , заголовок = "GFG" )

.Panel (рамка)

text1 = wx.StaticText (pa, label = "GEEKS FOR GEEKS" , pos = = = , 50 ))

рама.Показать ()

app1.Mainloop ()

Выход:

Пример # 2: 1255

00

39

9 9125 9125 9125 9125 9125 9125. import wx

app1 = wx.App ()

рамка = wx.Рамка ( Нет , заголовок = «приложение wxpython» )

pa = wx.Panel (рамка)

9398 wx.Button (pa, - 1 , "Button1" , pos = ( 120 , 100 ) 98398

рама.Показать ()

app1.Mainloop ()

Выход:

Пример № 3: CheckBox с использованием

52

  • CheckBox с использованием 2
  • wx

    приложение1 = wx.App ()

    рамка = wx title.Frame ( "wxpython app" )

    pa = wx.Панель (каркас)

    e = wx.CheckBox (pa, - 1 , "CheckBox1" 9039 9039 9039 9039 9039 9039 120 , 100 ))

    e = wx.CheckBox (pa, - 1 , "CheckBox8 ( 120 , 120 ))

    рама.Показать ()

    app1.Mainloop ()

    Выход:

    Пример # 4: RadioButtons с использованием w1254

    Импорт RadioButtons

    app1 = wx.App ()

    frame = wx.Frame ( 39 None) wxpython app " )

    pa = wx.Панель (рама)

    e = wx.RadioButton (pa, - 1 , "RadioButton1" 9039 = 9039 120, , , , , 100, , )) ( 120 , 120 ))

    рама.Показать ()

    app1.Mainloop ()

    Выход:

    Внимание, компьютерщик! Укрепите свои основы с помощью курса Python Programming Foundation и изучите основы.

    Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS .

    python - PlayOnLinux не работает с wxPython 4.1.0 - ImportError: Нет модуля с именем wxversion, должен быть wx.версия вместо

    Последняя версия wxPython не поддерживает модуль wxversion. Вместо этого информация доступна как wx.version.

    Есть ли какие-нибудь предложения по этому поводу? Спасибо!

    Моя среда - Ubuntu 20.04 LTS, pyenv, python 3.8.3, python 2.7.18, wxPython 4.1.0

      Политика $ apt-cache playonlinux
    playonlinux:
      Установлено: 4.3.4-1ubuntu1
      Кандидат: 4.3.4-1ubuntu1
      Таблица версий:
     *** 4.3.4-1ubuntu1 500
            500 http://us.archive.ubuntu.com/ubuntu focal / multiverse пакетов amd64
            500 http://us.archive.ubuntu.com/ubuntu focal / multiverse пакетов i386
            100 / var / lib / dpkg / статус
    
    $ which playonlinux
    / USR / bin / playonlinux
    
    # *** примечание: я использую pyenv ***
    
    $ pyenv локальный 2.7.18
    
    $ which python2
    /home/dever/.pyenv/shims/python2
    
    $ python2 -V
    Python 2.7.18
    
    $ pyenv локальный 3.8.3
    
    $ which python3
    /home/dever/.pyenv/shims/python3
    
    $ python3 -V
    Python 3.8.3
    
      

    Установлен Python 3.Конфигурация 8.3 имеет wxPython 4.1.0

      $ питон
    Python 3.8.3 (по умолчанию, 16 июля 2020 г., 20:35:40)
    [GCC 9.3.0] в Linux
    Для получения дополнительной информации введите «помощь», «авторские права», «кредиты» или «лицензия».
    >>> импортировать wx
    >>> печать (wx.version)
    <версия функции по адресу 0x7ff77d3cbd30>
    >>> печать (wx.version ())
    4.1.0 gtk3 (феникс) wxWidgets 3.1.4
    >>> выйти ()
      

    Следовательно, команда playonlinux выдает следующую ошибку:

      $ playonlinux
    Ищу питон... 3.8.3 - пропущено
    Ищем python2.7 ... 2.7.18 - Отслеживание (последний вызов последний):
      Файл "/usr/share/playonlinux/python/check_python.py", строка 1, в 
        импорт ОС, wxversion
    ImportError: нет модуля с именем wxversion
    неудавшиеся тесты
    Ищем python2.6 ...
    Ищем python2 ... 2.7.18 - Отслеживание (последний вызов последний):
      Файл "/usr/share/playonlinux/python/check_python.py", строка 1, в 
        импорт ОС, wxversion
    ImportError: нет модуля с именем wxversion
    неудавшиеся тесты
    Пожалуйста, установите python перед запуском этой программы
    
      

    ПРИМЕЧАНИЕ. Для тех, кто пытается установить wxPython на Ubuntu 20.04 LTS из-за ошибки GTK + *** Не удалось запустить тестовую программу GTK +, выясняем, почему ...

    Попробуйте эту команду (здесь: https://wxpython.org/pages/downloads/)

      pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04 wxPython
      

    Для получения дополнительной информации см. Также: https://discuss.wxpython.org/t/where-to-obtain-wxversion-py/28752

    playonlinux изначально установлен следующим образом, но переустановлен со стандартным репозиторием на Ubuntu 20.04 LTS (я обновился с 19.10):

    Версия playonlinux, которую я использую, предназначена для Ubuntu 18.04 (Bionic Version), загруженная отсюда: https://www.playonlinux.com/en/download.html

      Для версии Bionic
    
    Введите следующие команды:
    wget -q "http://deb.playonlinux.com/public.gpg" -O- | sudo apt-key добавить -
    sudo wget http://deb.playonlinux.com/playonlinux_bionic.list -O /etc/apt/sources.list.d/playonlinux.list
    sudo apt-get update
    sudo apt-get install playonlinux
      

    Может быть, playonlinux заменен версией flatpak?

    Глядя на ссылку Github на https: // www.playonlinux.com перенесет вас на https://github.com/PhoenicisOrg/, где предполагается, что, возможно, решение состоит в переходе на версию flatpak:

    https://flathub.org/apps/details/org.phoenicis.playonlinux

    Создание графического интерфейса пользователя с помощью wxPython | Учебники

    wxPython - это библиотека с открытым исходным кодом для простого создания графических пользовательских интерфейсов (GUI), которые будут работать на разных платформах. wxPython - это оболочка для популярного пакета wxWidgets , который представляет собой зрелую кроссплатформенную библиотеку C ++.

    Часто, когда мы пишем скрипты на Python, мы запускаем их через командную строку, например:

    Python myscript.py

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

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

    Создание объекта wx.Frame

    Начните с установки wxPython:

    pip install wxpython

    Примечание. Если вы работаете в Linux и у вас возникли проблемы с установкой wxPython, вам могут потребоваться установленные библиотеки GTK + и OpenGL.Попробуйте выполнить следующие команды, чтобы завершить установку:

    sudo apt-get install dpkg-dev build-essential python2.7-dev python3.5-dev python3.6-dev libgstreamer-plugins-base1.0-dev libnotify-dev libwebkitgtk-3.0-dev libwebkit-dev libwebkitgtk- разработчик libjpeg-dev libtiff-dev libgtk2.0-dev libsdl1.2-dev libgstreamer-plugins-base0.10-dev freeglut3 freeglut3-dev
    pip install --upgrade --pre -f https://wxpython.org/Phoenix/snapshot-builds/ wxPython

    Затем создайте скрипт под названием Calculator.py и откройте его в своей среде IDE. Теперь добавьте следующий код:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15 
     импорт wx
    
    Интерфейс класса (wx.Frame):
        def __init __ (я, родитель, заголовок):
            super (Интерфейс, сам) .__ init __ (родительский, заголовок = заголовок)
    
            # Показать окно на экране
            self.Show ()
    
    если __name__ == '__main__':
        # Создаем объект приложения
        app = wx.App ()
        Интерфейс (Нет, title = 'Calculator')
    
        приложение.MainLoop ()
     

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

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

     класс Интерфейс (wx.Frame):
     

    Мы создаем класс с именем Interface , который наследуется от объекта wxPython Frame . Фрейм - важный виджет, используемый в качестве контейнера для других виджетов. Когда объект Interface создается в строке 13 с его первым аргументом как None , это указывает на то, что у кадра нет родителя и он является виджетом верхнего уровня.

    Затем мы должны вызвать метод show для отображения кадра на экране.

    Последняя строка нашего скрипта запускает бесконечный цикл, который фиксирует все события, происходящие во время работы приложения (который для нашего калькулятора будет включать такие вещи, как нажатия кнопок и клавиш).

    Теперь, если вы откроете командную строку, перейдите в папку, содержащую наш скрипт, и выполните следующую команду:

    Python Calculator.py

    ... и вы увидите очень простое окно, подобное приведенному ниже:

    Не совсем умопомрачительный, но это начало. Мы можем контролировать размер нашего приложения, добавляя аргумент size в конструктор super () для __init__ :

     super (Интерфейс, сам).__init __ (родитель, заголовок = заголовок, размер = (300, 400))
     

    Здесь мы указали ширину из 300 пикселей и высоту из 400 пикселей.

    Перейдем к созданию каркаса нашего калькулятора.

    Макеты и работа с сайзерами wxPython

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

    Нам понадобятся такие кнопки, как «+», «-» и «=», а также все цифровые кнопки (0–9). Нам понадобится какой-то текстовый вывод для отображения расчета и его результата, а также нам может понадобиться поле, в котором мы можем вручную ввести уравнение.

    Стилем и компоновкой этих виджетов можно легко управлять в 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 
     импорт wx
    
    
    класс Интерфейс (wx.Рамка):
        def __init __ (я, родитель, заголовок):
            super (Интерфейс, сам) .__ init __ (родительский, заголовок = заголовок)
    
            # Показать окно на экране
            self.setup ()
            self.Show ()
    
        def setup (self):
            box = wx.BoxSizer (wx.VERTICAL)
            сетка = wx.GridSizer (1, 4, 10, 10)
    
            grid.AddMany ([
                (wx.Button (self, label = '+'), 0, wx.EXPAND),
                (wx.Button (self, label = '-'), 0, wx.EXPAND),
                (wx.Button (self, label = 'x'), 0, wx.EXPAND),
                (wx.Button (self, label = '/'), 0, wx.РАСШИРЯТЬ),
            ])
    
            box.Add (сетка, пропорция = 1, флаг = wx.EXPAND)
            self.SetSizer (поле)
    
    
    если __name__ == '__main__':
        # Создаем объект приложения
        app = wx.App ()
        Интерфейс (Нет, title = 'Calculator')
    
        app.MainLoop ()
     

    Если вы запустите в консоли команду python Calculator.py , вы должны увидеть что-то вроде изображения ниже:

    Давайте разберемся, что происходит в коде.

    Вы, надеюсь, заметили, что мы добавили новый метод под названием setup , и внутри этого метода вы увидите, что мы создали две переменные, названные box и grid .Обе эти переменные используются для хранения объектов wxPython sizer , которые используются для управления размером, позиционированием и даже изменением размера виджетов в вашем приложении.

     настройка по умолчанию (самостоятельно):
            box = wx.BoxSizer (wx.VERTICAL)
     

    Переменная box используется для хранения объекта wxPython BoxSizer . Этот классификатор позволяет нам размещать множество других виджетов или классификаторов в строках и столбцах.Здесь мы предоставили аргумент для BoxSizer с wx.Vertical , который указывает, что мы хотим, чтобы ориентация была вертикальной .

     сетка = wx.GridSizer (1, 4, 10, 10)
     

    Переменная grid содержит объект GridSizer . Объект GridSizer устанавливает строки и столбцы в формате таблицы, причем каждая ячейка внутри таблицы имеет одинаковый размер.Объект GridSizer принимает четыре аргумента: строки , столбца , вертикальный зазор и горизонтальный зазор . Итак, здесь мы указали, что нам нужно 1 строк, 4 столбцов и вертикальное / горизонтальное пространство 10 пикселей.

    Затем мы добавили четыре кнопки в строку GridSizer:

     grid.AddMany ([
                (wx.Button (self, label = '+'), 0, wx.EXPAND),
                (wx.Кнопка (self, label = '-'), 0, wx.EXPAND),
                (wx.Button (self, label = 'x'), 0, wx.EXPAND),
                (wx.Button (self, label = '/'), 0, wx.EXPAND)
            ])
     

    Для одновременного добавления нескольких виджетов в классификатор можно использовать метод AddMany () . Виджеты будут добавлены в том порядке, в котором они появляются, заполняя первую строку, затем вторую и так далее.

    Мы использовали встроенный объект wx.Button для создания наших четырех кнопок и присвоили каждой из них определенную метку для отображения на кнопке.

    0 определяет флаг пропорции. Этот флаг определяет масштаб виджета по оси его ориентации. Таким образом, если мы добавим виджеты с флагом пропорции больше 0 в BoxSizer с горизонтальным выравниванием, тогда виджеты будут масштабироваться по горизонтальной оси . Виджет с пропорцией 2 будет увеличен в два раза больше, чем виджет с пропорцией 1, в то время как виджет с пропорцией 0 не будет масштабирован. Флаг пропорции не используется для GridSizer , такого как наш калькулятор, потому что все ячейки таблицы создаются одинакового размера.

    Флаг wx.EXPAND указывает виджету использовать все пространство вдоль другой оси. Таким образом, добавление виджета с флагом wx.EXPAND к BoxSizer с горизонтальным выравниванием расширит элементы на вертикальной оси .

     box.Add (сетка, пропорция = 1, флаг = wx.EXPAND)
            self.SetSizer (поле)
     

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

    Теперь, когда мы понимаем, как GridSizer определяет строки, столбцы и ячейки, мы можем добавить оставшиеся кнопки, которые нам нужны, в наш калькулятор. Начните с изменения GridSizer , чтобы он имел четыре строки:

     сетка = wx.GridSizer (4, 4, 10, 10)
     

    ... а затем заполните строки следующим образом:

     16
    17
    18
    19
    20
    21 год
    22
    23
    24
    25
    26 год
    27
    28 год
    29
    30
    31 год
    32
    33 
     сетка.AddMany ([
                (wx.Button (self, label = '7'), 0, wx.EXPAND),
                (wx.Button (self, label = '8'), 0, wx.EXPAND),
                (wx.Button (self, label = '9'), 0, wx.EXPAND),
                (wx.Button (self, label = '/'), 0, wx.EXPAND),
                (wx.Button (self, label = '4'), 0, wx.EXPAND),
                (wx.Button (self, label = '5'), 0, wx.EXPAND),
                (wx.Button (self, label = '6'), 0, wx.EXPAND),
                (wx.Button (self, label = '*'), 0, wx.EXPAND),
                (wx.Button (self, label = '1'), 0, wx.РАСШИРЯТЬ),
                (wx.Button (self, label = '2'), 0, wx.EXPAND),
                (wx.Button (self, label = '3'), 0, wx.EXPAND),
                (wx.Button (self, label = '-'), 0, wx.EXPAND),
                (wx.Button (self, label = '0'), 0, wx.EXPAND),
                (wx.Button (self, label = '.'), 0, wx.EXPAND),
                (wx.Button (self, label = '='), 0, wx.EXPAND),
                (wx.Button (self, label = '+'), 0, wx.EXPAND)
            ])
     

    Если вы запустите python Calculator.py в консоли, теперь у вас должно быть приложение, которое очень похоже на калькулятор! К сожалению, он еще не совсем готов, чтобы начать расчет ваших чаевых, но мы можем это исправить.

    Привязка событий wxPython к кнопкам

    Следующий шаг - привязать событие к каждой из вышеперечисленных кнопок, чтобы они могли выполнять действие в соответствии с их меткой. События являются неотъемлемой частью приложений с графическим интерфейсом пользователя, которые позволяют им реагировать на различные типы действий. События включают в себя такие вещи, как нажатие клавиши на клавиатуре, перемещение мыши или нажатие кнопки.

    Выше мы обсуждали тот факт, что строка app.MainLoop () создала наш цикл событий.Этот цикл событий теперь ожидает, когда мы инициируем событие, нажав одну из наших кнопок. Но прежде чем цикл событий сможет захватывать наши события, нам нужно фактически привязать тип события к нашим кнопкам.

    Для этого мы собираемся немного реорганизовать наш код. Если вы не знакомы с термином «рефакторинг», это просто означает, что мы собираемся реструктурировать наш код, не изменяя способ его работы, то есть мы собираемся привязывать события к нашим кнопкам, не меняя макет нашего калькулятора.

    Мы собираемся провести рефакторинг кода:

     сетка = wx.GridSizer (4, 4, 10, 10)
    
            grid.AddMany ([
                (wx.Button (self, label = '7'), 0, wx.EXPAND),
                (wx.Button (self, label = '8'), 0, wx.EXPAND),
                ...
            ])
     

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

     14
    15
    16
    17
    18
    19
    20
    21 год
    22
    23
    24
    25
    26 год
    27 
     сетка = wx.GridSizer (5, 4, 10, 10)
    
            кнопки = [
                «7», «8», «9», «/»,
                «4», «5», «6», «*»,
                '1', '2', '3', '-',
                '0', '.', 'C', '+',
                знак равно
            ]
    
            для метки в кнопках:
                button = wx.Button (сам, -1, метка)
                grid.Add (кнопка, 0, wx.EXPAND)
                self.Bind (wx.EVT_BUTTON, self.on_button_press, кнопка)
     

    По сути, мы заменили метод AddMany () на цикл для , который циклически перебирает наши метки кнопок и создает виджет кнопки с соответствующей меткой.Затем кнопка добавляется к GridSizer , а затем мы привязываем к кнопке событие нажатия кнопки wxPython, то есть wx.EVT_BUTTON .

    Мы могли бы создать ту же функциональность без цикла для , но нам пришлось бы создавать и связывать каждую кнопку вручную. Реорганизовав наш код, мы не только сократили его и улучшили читаемость, но и улучшили его ремонтопригодность. Теперь, если вы хотите добавить дополнительную кнопку в свой калькулятор, все, что вам нужно сделать, это добавить метку в список кнопок .

    Кодирование нашего обработчика событий

    Теперь у вас должен быть калькулятор с несколькими кнопками, но отсутствует один ключевой элемент - дисплей для нашего ввода / вывода. Мы можем исправить это быстро, добавив wxPython TextCtrl следующим образом:

     коробка = wx.BoxSizer (wx.VERTICAL)
            self.textbox = wx.TextCtrl (self, style = wx.TE_RIGHT)
            box.Add (self.textbox, flag = wx.EXPAND | wx.TOP | wx.BOTTOM, border = 4)
     

    Теперь ваш код должен выглядеть так:

     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 
     импорт wx
    
    
    класс Интерфейс (wx.Рамка):
        def __init __ (я, родитель, заголовок):
            super (Интерфейс, сам) .__ init __ (родитель, заголовок = заголовок, размер = (300, 400))
    
            # Показать окно на экране
            self.setup ()
            self.Show ()
    
        def setup (self):
            box = wx.BoxSizer (wx.VERTICAL)
            self.textbox = wx.TextCtrl (self, style = wx.TE_RIGHT)
            box.Add (self.textbox, flag = wx.EXPAND | wx.TOP | wx.BOTTOM, border = 4)
    
            сетка = wx.GridSizer (5, 4, 10, 10)
    
            кнопки = [
                «7», «8», «9», «/»,
                «4», «5», «6», «*»,
                '1', '2', '3', '-',
                '0', '.',' C ',' + ',
                знак равно
            ]
    
            для метки в кнопках:
                button = wx.Button (сам, -1, метка)
                grid.Add (кнопка, 0, wx.EXPAND)
                self.Bind (wx.EVT_BUTTON, self.on_button_press, кнопка)
    
            box.Add (сетка, пропорция = 1, флаг = wx.EXPAND)
            self.SetSizer (поле)
    
    если __name__ == '__main__':
        # Создаем объект приложения
        app = wx.App ()
        Интерфейс (Нет, title = 'Calculator')
    
        app.MainLoop ()
     

    Теперь мы связали каждое нажатие кнопки с функцией под названием on_button_press .Эта функция известна как обработчик событий , поскольку она содержит код, отвечающий за реакцию на событие. Поэтому нам нужно закодировать наш обработчик события on_button_press , чтобы он реагировал на ... ну ... нажатие кнопки.

    Создайте новый метод после метода setup с именем on_button_press и добавьте следующий код:

     35
    36
    37
    38
    39
    40
    41 год
    42
    43 год
    44 год
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57 
     def on_button_press (self, e):
    
            # Получить метку кнопки
            label = e.GetEventObject (). GetLabel ()
    
            # Получаем ввод от TextCtrl
            расчет = self.textbox.GetValue ()
    
            # Обработка события на основе нажатой кнопки
            if label == '=': # Вычислить результат ввода в TextCtrl
                # Игнорировать пустой расчет
                если не расчет:
                    возвращаться
    
                результат = eval (расчет)
    
                # Показать результат
                self.textbox.SetValue (str (результат))
            elif label == 'C': # Очистить TextCtrl
                себя.текстовое поле.SetValue ('')
            иначе: # 0-9 (и.)
                # Добавляем метку нажатия кнопки к текущему вычислению в TextCtrl
                self.textbox.SetValue (расчет + метка)
     

    С этой функцией наш калькулятор теперь сможет реагировать на нажатия кнопок и вычислять результат ввода. Если вы запустите в консоли команду python Calculator.py , вы должны увидеть что-то вроде изображения ниже:

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

     def on_button_press (self, e):
    
                # Получить метку кнопки
                label = e.GetEventObject (). GetLabel ()
     

    Определен метод on_button_press , которому передается объект события для нажатой кнопки. Мы используем этот объект события, чтобы получить метку кнопки ('9', 'C', '=' и т. Д.).

     расчет = сам.текстовое поле.GetValue ()
     

    Затем мы также берем текущий ввод из TextCtrl и назначаем его переменной вычисление .

    Если нажата кнопка равенства, нам нужно вычислить результат текущего ввода, отображаемого в TextCtrl , сохраненном в вычислении .

     если не расчет:
                    возвращаться
     

    Если ввод пуст (и, следовательно, нечего рассчитывать), мы можем просто завершить функцию с возвратом .

     результат = eval (вычисление)
     

    С другой стороны, если TextCtrl не пуст, то нам нужно вычислить результат и отобразить его. К счастью, в Python есть очень полезная и мощная встроенная функция под названием eval . eval может интерпретировать строку как код и вернуть результат. Таким образом, мы можем передать функциональные строки eval , такие как '2 x 3' и '10 - 5 ', и он вернет нам 6 и 5 .Это избавляет нас от необходимости самостоятельно создавать много кода.

    Примечание. Будьте осторожны при использовании метода eval . eval выполнит любой действительный код Python, который ему предоставлен, поэтому вам следует избегать комбинирования его с пользовательским вводом, чтобы предотвратить запуск вредоносного кода через ваше приложение.

     self.textbox.SetValue (str (результат))
     

    После того, как ввод был оценен, результат устанавливается как значение TextCtrl .

     elif label == 'C': # Очистить TextCtrl
                self.textbox.SetValue ('')
     

    При нажатии кнопки очистки значение TextCtrl устанавливается на пустую строку.

     иначе: # 0-9 (и.)
                # Добавляем метку нажатия кнопки к текущему вычислению в TextCtrl
                self.textbox.SetValue (расчет + метка)
     

    Наконец, если будет нажата что-либо, кроме кнопок равенства или очистки, т.е.е. 0-9 или десятичная точка, то метка кнопки добавляется к текущему вычислению в TextCtrl .

    Диалоги и обработка исключений

    Калькулятор теперь работает так, как и следовало ожидать, но есть еще одна вещь, о которой нам действительно нужно позаботиться. Если пользователь вводит неверное вычисление, например 2 - + 3 или 2 * Penguin , Python вызовет исключение. Мы можем поймать эти исключения с помощью try / except и использовать это, чтобы вернуть пользователю сообщение, чтобы он мог исправить свою ошибку.Мы можем сделать это с помощью диалогов .

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

    Давайте реорганизуем наш метод on_button_press с помощью блока try / except , чтобы отловить любые ошибки ввода, и использовать встроенный диалог wx.LogError , чтобы сообщить об ошибках пользователю. Замените строку результат = eval (вычисление) следующим кодом:

     49
    50
    51
    52
    53
    54
    55
    56
    57 
     попробуйте:
                    # Рассчитываем результат
                    результат = eval (расчет)
                кроме SyntaxError как err: # Перехватить любые ошибки ввода (например,грамм. '6 + * 2')
                    wx.LogError ('Неверный синтаксис ({}). Проверьте введенные данные и повторите попытку.'. формат (расчет))
                    возвращаться
                кроме NameError как err: # Перехватить любые введенные вручную ошибки (например, '2 x три')
                    wx.LogError ('Произошла ошибка. Проверьте введенные данные и повторите попытку.')
                    возвращаться
     

    Мы добавляем try перед методом eval , где мы столкнемся с любыми исключениями, если вычисление окажется неверным.

     за исключением SyntaxError как err: # Перехват любых ошибок ввода (например, '6 + * 2')
                    wx.LogError ('Неверный синтаксис ({}). Проверьте введенные данные и повторите попытку.'. формат (расчет))
                    возвращаться
     

    Мы используем исключение SyntaxError , чтобы отловить любые ошибки в формате операторов, такие как сочетание сложения и вычитания. Если возникает этот тип исключения, для информирования пользователя о проблеме используется диалоговое окно LogError .

     за исключением NameError как err: # Перехват любых ошибок, набранных вручную (например, «2 x три»)
                    wx.LogError ('Произошла ошибка. Проверьте введенные данные и повторите попытку.')
                    возвращаться
     

    Мы также используем исключение NameError , чтобы перехватить любой неожиданный ввод, который пользователь мог попытаться ввести вручную в TextCtrl . Вы можете подумать, что 2 * Penguin должен возвращать двух пингвинов, но, к сожалению, метод eval не так уж и сложен.

    И вот оно; полностью рабочий калькулятор! Полный сценарий должен выглядеть следующим образом:

     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
    65
    66
    67
    68
    69
    70
    71
    72
    73 
     импорт wx

    Интерфейс класса (wx.Frame):
    def __init __ (я, родитель, заголовок):
    super (Интерфейс, сам).__init __ (родитель, заголовок = заголовок, размер = (300, 400))

    # Показать окно на экране
    self.setup ()
    self.Show ()

    def setup (self):
    box = wx.BoxSizer (wx.VERTICAL)
    self.textbox = wx.TextCtrl (self, style = wx.TE_RIGHT)
    box.Add (self.textbox, flag = wx.EXPAND | wx.TOP | wx.BOTTOM, border = 4)

    сетка = wx.GridSizer (5, 4, 10, 10)

    кнопки = [
    «7», «8», «9», «/»,
    «4», «5», «6», «*»,
    '1', '2', '3', '-',
    '0', '.',' C ',' + ',
    знак равно
    ]

    для метки в кнопках:
    button = wx.Button (сам, -1, метка)
    grid.Add (кнопка, 0, wx.EXPAND)
    self.Bind (wx.EVT_BUTTON, self.on_button_press, кнопка)

    box.Add (сетка, пропорция = 1, флаг = wx.EXPAND)
    self.SetSizer (поле)

    def on_button_press (self, e):

    # Получить метку кнопки
    label = e.GetEventObject (). GetLabel ()

    # Получаем ввод от TextCtrl
    расчет = self.textbox.GetValue ()

    # Обработка события на основе нажатой кнопки
    if label == '=': # Вычислить результат ввода в TextCtrl
    # Игнорировать пустой расчет
    если не расчет:
    возвращаться

    пытаться:
    # Рассчитываем результат
    результат = eval (расчет)
    кроме SyntaxError как err: # Перехватить любые ошибки ввода (например,грамм. '6 + * 2')
    wx.LogError ('Неверный синтаксис ({}). Проверьте введенные данные и повторите попытку.'. формат (расчет))
    возвращаться
    кроме NameError как err: # Перехватить любые введенные вручную ошибки (например, '2 x три')
    wx.LogError ('Произошла ошибка. Проверьте введенные данные и повторите попытку.')
    возвращаться

    # Показать результат
    self.textbox.SetValue (str (результат))
    elif label == 'C': # Очистить TextCtrl
    self.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    2021 © Все права защищены. Карта сайта