Как написать свою программу с интерфейсом

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

Обзор графических библиотек

Строить графический интерфейс пользователя ( GUI , G raphical U ser I nterface) для программ на языке Python можно при помощи соответствующих библиотек компонентов графического интерфейса или, используя кальку с английского, библиотек виджетов.

Следующий список далеко не полон, но отражает многообразие существующих решений:

  • Tkinter Многоплатформенный пакет имеет хорошее управление расположением компонентов. Интерфейс выглядит одинаково на различных платформах (Unix, Windows, Macintosh). Входит в стандартную поставку Python. В качестве документации можно использовать руководство «An Introduction to Tkinter» («Введение в Tkinter»), написанное Фредриком Лундом: http://www.pythonware.com/library/tkinter/introduction/
  • wxPython Построен на многоплатформной библиотеке wxWidgets (раньше называлась wxWindows). Выглядит родным для всех платформ, активно совершенствуется, осуществлена поддержка GL. Имеется для всех основных платформ. Возможно, займет место Tkinter в будущих версиях Python. Сайт: http://www.wxpython.org/
  • PyGTK Набор визуальных компонентов для GTK+ и Gnome. Только для платформы GTK.
  • PyQT/PyKDE Хорошие пакеты для тех, кто использует Qt (под UNIX или Windows) или KDE.
  • Pythonwin Построен вокруг MFC , поставляется вместе с оболочкой в пакете win32all; только для Windows.
  • pyFLTK Аналог Xforms, поддержка OpenGL . Имеется для платформ Windows и Unix. Сайт: http://pyfltk.sourceforge.net/
  • AWT , JFC , Swing Поставляется вместе с Jython, а для Jython доступны средства, которые использует Java. Поддерживает платформу Java.
  • anygui Независимый от нижележащей платформы пакет для построения графического интерфейса для программ на Python. Сайт: http://anygui.sourceforge.net/
  • PythonCard Построитель графического интерфейса, сходный по идеологии с HyperCard/MetaCard. Разработан на базе wxPython . Сайт: http://pythoncard.sourceforge.net/

Список актуальных ссылок на различные графические библиотеки, доступные из Python , можно найти по следующему адресу: http://phaseit.net/claird/comp.lang.python/python_GUI.html

Изучение TKinter за 8 минут / Разработка GUI программы на Python

Библиотеки могут быть многоуровневыми. Например, PythonCard использует wxPython, который, скажем, на платформе Linux базируется на многоплатформной GUI -библиотеке wxWindows, которая, в свою очередь , базируется на GTK+ или на Motif , а те — тоже используют для вывода X Window. Кстати, для Motif в Python имеются свои привязки.

В лекции будет рассматриваться пакет Tkinter, который по сути является оберткой для Tcl /Tk — известного графического пакета для сценарного языка Tcl . На примере этого пакета легко изучить основные принципы построения графического интерфейса пользователя.

Сделал Java программу с интерфейсом / Погодное приложение

О графическом интерфейсе

Почти все современные графические интерфейсы общего назначения строятся по модели WIMP — Window, Icon , Menu , Pointer (окно, иконка, меню , указатель ). Внутри окон рисуются элементы графического интерфейса, которые для краткости будут называться виджетами ( widget — штучка). Меню могут располагаться в различных частях окна, но их поведение достаточно однотипно: они служат для выбора действия из набора предопределенных действий. Пользователь графического интерфейса «объясняет» компьютерной программе требуемые действия с помощью указателя. Обычно указателем служит курсор мыши или джойстика, однако есть и другие «указательные» устройства. С помощью иконок графический интерфейс приобретает независимость от языка и в некоторых случаях позволяет быстрее ориентироваться в интерфейсе.

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

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

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

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

Источник: intuit.ru

Записки программиста

Пишем GUI-приложение при помощи Python, GTK и Glade

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

Установка зависимостей (Glade нужен только на время разработки):

sudo apt-get install python3-gi glade

Код самого скрипта:

# gtk-example.py
# (c) Aleksander Alekseev 2016
# http://eax.me/

import signal
import os
import gi
gi. require_version ( ‘Gtk’ , ‘3.0’ )
gi. require_version ( ‘Notify’ , ‘0.7’ )
from gi. repository import Gtk
from gi. repository import Notify

Читайте также:
Как работать с программой pro

APPID = «GTK Test»
CURRDIR = os . path . dirname ( os . path . abspath ( __file__ ) )
# could be PNG or SVG as well
ICON = os . path . join ( CURRDIR , ‘python3.xpm’ )

# Cross-platform tray icon implementation
class TrayIcon:

def __init__ ( self , appid , icon , menu ) :
self . menu = menu

APPIND_SUPPORT = 1
try :
from gi. repository import AppIndicator3
except :
APPIND_SUPPORT = 0

if APPIND_SUPPORT == 1 :
self . ind = AppIndicator3. Indicator . new (
appid , icon ,
AppIndicator3. IndicatorCategory . APPLICATION_STATUS )
self . ind . set_status ( AppIndicator3. IndicatorStatus . ACTIVE )
self . ind . set_menu ( self . menu )
else :
self . ind = Gtk. StatusIcon ( )
self . ind . set_from_file ( icon )
self . ind . connect ( ‘popup-menu’ , self . onPopupMenu )

def onPopupMenu ( self , icon , button , time ) :
self . menu . popup ( None , None , Gtk. StatusIcon . position_menu , icon ,
button , time )

def __init__ ( self ) :
self . window_is_hidden = False

def onShowButtonClicked ( self , button ) :
msg = «Clicked: » + entry. get_text ( )
dialog = Gtk. MessageDialog ( window , 0 , Gtk. MessageType . INFO ,
Gtk. ButtonsType . OK , msg )
dialog. run ( )
dialog. destroy ( )

def onNotify ( self , *args ) :
Notify. Notification . new ( «Notification» , «Hello!» , ICON ) . show ( )

def onShowOrHide ( self , *args ) :
if self . window_is_hidden :
window. show ( )
else :
window. hide ( )

self . window_is_hidden = not self . window_is_hidden

def onQuit ( self , *args ) :
Notify. uninit ( )
Gtk. main_quit ( )

# Handle pressing Ctr+C properly, ignored by default
signal . signal ( signal . SIGINT , signal . SIG_DFL )

builder = Gtk. Builder ( )
builder. add_from_file ( ‘gtk-example.glade’ )
builder. connect_signals ( Handler ( ) )

window = builder. get_object ( ‘window1’ )
window. set_icon_from_file ( ICON )
window. show_all ( )

entry = builder. get_object ( ‘entry1’ )
menu = builder. get_object ( ‘menu1’ )
icon = TrayIcon ( APPID , ICON , menu )
Notify. init ( APPID )

Примечание: Насколько я смог разобраться, используемый здесь пакет обычно называют «PyGObject bindings». Существует очень похожий пакет PyGTK, но его не рекомендуется использовать в новых проектах даже на официальном сайте самого PyGTK. Поэтому в этой заметке мы его и не используем.

А вот скриншот, показывающий все возможности программы:

Пример GUI на Python и GTK

Скрипт был проверен на Linux с Unity, Linux с Xfce, а также FreeBSD с i3. Во FreeBSD для работы приложения требуется установить пакет py34-gobject3.

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

Но на всякий случай все же отмечу, что сам интерфейс описывается в XML-файле с расширением .glade, который был создан в режиме WYSIWYG при помощи программы Glade. Так как XML является текстовым форматом, его очень здорово хранить в Git. Притом XML генерируется очень компактный и отлично читаемый. Пользоваться Glade очень просто, поэтому не стану заострять на нем внимание. Лайоут строится при помощи боксов по тому же принципу, что и в wxWidgets.

Связывание событий и хэндлеров происходит при помощи вот этой строчки:

builder. connect_signals ( Handler ( ) )

При этом имена методов класса Handler пишутся прямо-таки текстом в Glade. Просто старый-добрый Delphi в самом хорошем смысле. Быстро наклепал, и заработало!

С иконкой в трее все немного непросто. В зависимости от используемого вами десктоп окружения для ее отображения следует использовать либо AppIndicator3, либо Gtk.StatusIcon. Например, в Unity работает только AppIndicator3, а вот в i3 соответствующий .typelib файл просто отсутствует, и нужно использовать Gtk.StatusIcon. А в Xfce работает и так, и так.

Интересную сводную таблицу по теме можно найти в комментариях к коду Syncthing-GTK. Кстати, Syncthing недавно обозревался в этом блоге.

  • https://python-gtk-3-tutorial.readthedocs.io/en/latest/;
  • https://lazka.github.io/pgi-docs/;
  • https://glade.gnome.org/;

Полную версию исходного кода к посту вы найдете на GitHub.

Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.

Источник: eax.me

Создание приложения с использованием виджетов

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

В данный момент вы не можете посмотреть или раздать видеоурок ученикам

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

Получите невероятные возможности

1. Откройте доступ ко всем видеоурокам комплекта.

2. Раздавайте видеоуроки в личные кабинеты ученикам.

3. Смотрите статистику просмотра видеоуроков учениками.
Получить доступ

Конспект урока «Создание приложения с использованием виджетов»

Вопросы:

· Элементы управления: кнопки, метки и поля ввода.

· Создание и настройка окон сообщений.

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

Вначале с помощью редактора QtDesigner создадим пользовательский интерфейс приложения. Создадим форму для главного окна и настроим её размер.

Разместим на форме главного окна элемент управления Line Edit. Это будет поле ввода для первого числа. Настроим его размеры и изменим имя его объекта. Назовём его txtNum1. Скопируем его, выделив и используя сочетание клавиш Ctrl+C.

Разместим копию поля ввода на форме, используя сочетание клавиш Ctrl+V. Разместим его справа на небольшом расстоянии от предыдущего. Назовём это поле txtNum2. Это будет поле ввода для второго числа. Теперь разместим между двумя полями ввода компонент Label.

Это текстовая метка. Изменим текст метки на символ «+». Также изменим выравнивание текста в метке. За него отвечает свойство alignment. Есть горизонтальное и вертикальное выравнивания. Изменим горизонтальное выравнивание текста метки на выравнивание по центру. Настроим размер метки и выровняем её относительно полей ввода.

Создадим копию этой метки и разместим её справа от второго поля ввода. Изменим название объекта этой метки на lblSum, изменим текст метки на знак равенства, после чего установим её горизонтальное выравнивание по левому краю. Увеличим горизонтальный размер метки, так как позже в неё будем выводить сумму чисел, введённых пользователем в поля ввода.

Читайте также:
Как установить автоматическое обновление программ

Теперь разместим на форме, ниже остальных элементов управления, кнопку PushButton. Назовём её btnResult. Изменим текст кнопки на надпись «Вычислить». Выровняем её относительно остальных элементов управления. Сохраним созданную форму под именем sumGUI в каталоге по умолчанию.

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

И просмотрим его в среде разработки. Ранее мы кратко рассмотрели структуру модуля, сформированного приложением QtDesigner. В первых 7 строках, в комментариях, следует описание модуля. Далее следует класс UiMainWindow. Он описывает созданную нами форму. И после класса следует основная программа, которая создаёт объект указанного класса и запускает у него цикл обработки событий.

Класс UiMainWindow содержит методы setupUi и retranslateUi. Первый отвечает за создание и настройку формы, а также её элементов управления. Второй же метод отвечает за размещение текстовых надписей на элементах управления. Запустим модуль на выполнение. На экран было выведено окно, которое мы создали в приложении QtDesigner.

Нам нужно описать обработчик события, который будет вызываться при нажатии пользователем на кнопку «Вычислить». Для этого опишем в классе новый метод, назовём его getResult. У него будет единственный параметр – self. Работа метода будет начинаться с того, что мы считаем числа из полей ввода на форме. Считаем первое число в переменную n1.

Чтобы считать текст, введённый пользователем в поле ввода, нужно обратиться к нему. У нас поле ввода называется txtNum1. У этого поля ввода нужно вызвать метод, название которого совпадает с соответствующим свойством элемента управления. Нас интересует свойство text, поэтому вызовем метод text без параметров.

Он вернёт текстовую строку – значение соответствующего свойства. Нам нужно преобразовать эту строку в целое число. Для этого воспользуемся функцией int. Скопируем написанную строку кода и изменим её для считывания в переменную n2 текста из поля ввода txtNum2. Теперь в переменной s рассчитаем сумму значений переменных n1 и n2.

Далее нам нужно вывести результат расчёта в метку lblSum. Для этого у метки вызовем метод setText, он присваивает свойству text новое значение. Этот метод принимает на вход один текстовый параметр – новое значение поля. Зададим его как результат склейки двух символьных строк. Первая символьная строка будет содержать «= ». Второй строкой будет преобразованное в строковый тип значение переменной s.

def getResult (self):

n1 = int (txtNum1.text ())

n2 = int (txtNum2.text ())

self.lblSum.setText (‘= ‘ + str (s))

Описание метода getResult завершено. Теперь нужно сделать его обработчиком события нажатия на кнопку btnResult. Для этого в конце метода setupUi добавим строку кода, которая обращается к кнопке btnResult на форме. У этой кнопки нас интересует событие clicked. С помощью метода connect можно назначить этому событию обработчик.

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

Описание модуля завершено. Сохраним его и запустим на выполнение. На экране появилось окно, которое мы создали. Введём в поля ввода числа 3 и 5, после чего нажмём на кнопку «Вычислить». После знака равенства появилось число 8. Это действительно сумма введённых чисел. Пока наша программа работает правильно, но теперь уберём все данные из полей ввода и нажмём на кнопку «Вычислить».

Программа завершила своё исполнение ошибкой.

Так произошло потому, что мы не учли возможность ввода пользователем некорректных данных. Исправим это. Условимся, что в случае, если хотя бы одно из полей ввода окажется пустым, будем выводить на экран окно с соответствующим сообщением об ошибке. У вас наверняка возник вопрос: «Как же мы вызовем окно с сообщением об ошибке? Ведь мы не создали для него интерфейс.».

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

Изменим код функции getResult. Поместим весь код, который в ней содержится, в блок try… Далее опишем блок except. Создадим в переменной msg объект класса QMessageBox, который описан в модуле QtWidgets. Таким образом, у нас уже есть простое окно пока без сообщения об ошибке. Чтобы показать его, нужно у объектаmsg вызвать метод exec без параметров.

def getResult (self):

n1 = int (txtNum1.text ())

n2 = int (txtNum2.text ())

self.lblSum.setText (‘= ‘ + str (s))

Сохраним модуль и запустим его на выполнение. В окне программы оставим поля ввода пустыми и сразу нажмём на кнопку «Вычислить». На экран было выведено пустое окно с единственной кнопкой – «OK». Закроем программу.

Теперь настроим созданное окно. Для этого в классе QMessageBox реализовано несколько методов. Сначала зададим заголовок окна. Для этого между командами создания и вызова окна у объекта msg вызовем метод setWindowTitle. Как ясно из названия, этот метод задаёт значение свойства windowTitle, в котором хранится заголовок окна.

Зададим в качестве аргумента текстовую строку «Ошибка ввода». Теперь изменим текст окна. Для этого вызовем у объекта метод setText. Текст будет содержать сообщение о том, что не все данные заданы.

Снова сохраним модуль и запустим его на выполнение. Сразу нажмём на кнопку «Вычислить». На экран было выведено окно с заголовком «Ошибка ввода» и текстом о том, что не все данные заданы. На этом наша работа над окном ошибки не закончена.

Читайте также:
Какая программа на Андроид чтобы расплачиваться картой

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

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

def getResult (self):

n1 = int (txtNum1.text ())

n2 = int (txtNum2.text ())

self.lblSum.setText (‘= ‘ + str (s))

msg.setWindowTitle (‘Ошибка ввода’)

msg.setText (‘Не все данные заданы.’)

if self.txtNum1.text () == » and self.txtNum1.text () == »:

msg.setInformativeText (‘Оба поля ввода пусты.’)

msg.setInformativeText (‘Первое поле ввода пустое.’)

msg.setInformativeText (‘Второе поле ввода пустое.’)

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

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

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

def getResult (self):

n1 = int (txtNum1.text ())

n2 = int (txtNum2.text ())

self.lblSum.setText (‘= ‘ + str (s))

msg.setWindowTitle (‘Ошибка ввода’)

msg.setText (‘Не все данные заданы.’)

if self.txtNum1.text () == » and self.txtNum1.text () == »:

msg.setInformativeText (‘Оба поля ввода пусты.’)

msg.setInformativeText (‘Первое поле ввода пустое.’)

msg.setInformativeText (‘Второе поле ввода пустое.’)

Снова сохраним модуль и проверим наше сообщение об ошибке. На этот раз в окне с сообщением об ошибке присутствует значок предупреждения.

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

Опишем для этого метод changeText, который будет вызываться при изменении текста в одном из полей ввода. В самом начале метода сохраним в строковой переменной s текст из поля ввода. И тут перед нами встаёт вопрос: «Из какого поля ввода нужно взять текст? Ведь мы не знаем, в каком именно поле ввода он был изменён».

Для того, чтобы узнать, каким элементом управления было вызвано событие, нужно обратиться к текущему циклу обработки событий. Для этого из модуля QtCore, из класса QCoreApplication, вызывается метод instance. У текущего цикла обработки событий вызовем метод sender. На русский язык название этого метода можно перевести как «отправитель».

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

Запишем цикл с параметром i, в котором будем последовательно перебирать индексы символов строки s от последнего к первому, так как чаще всего новые символы добавляются в конец строки. В этом цикле, если мы найдём в строке s символ, не являющийся цифрой, то мы удалим его из строки, после чего завершим цикл. Так, если в процессе работы цикла в строке будет найден некорректный символ, то он будет удалён из строки. После работы цикла вызовем у объекта-отправителя метод setText, которому в качестве аргумента зададим изменённую строку s. Таким образом, если в поле будет введён некорректный символ, то он сразу будет удалён.

s = QtCore.QCoreApplication.instance ().sender ().text ()

for i in range (len (s) – 1, — 1, -1):

if not s[i].isdigit ():

s = s[0:i] + s[i + 1:len (s)]

Теперь в конце метода setupUi свяжем у поля ввода txtNum1 событие textChanged с описанным нами методом changeText. Скопируем эту строку кода и изменим её так, чтобы она связывала у поля txtNum2 то же событие с тем же методом.

Сохраним модуль и запустим его на выполнение. Теперь при попытке ввести в поле ввода любой символ, кроме цифры, он будет сразу удалён, однако это происходит так быстро, что мы просто не успеваем увидеть изменений в поле ввода. Попробуем задать числа сто и сорок пять. Их сумма действительно равна ста сорока пяти. Попробуем оставить второе поле ввода пустым.

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

· Как происходят создание и настройка таких компонентов, как поля ввода, метки и кнопки.

· Как создать приложение с графическим интерфейсом с использованием перечисленных элементов управления,

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru