Проект "Сравнение разработки графического интерфейса с помощью библиотек PyQt и Tkinter на примере программы 'Вычислитель дат и дней'"

Введение

К языку программирования Python существует ряд библиотек для разработки графического интерфейса пользователя: PyQt, Tkinter, PyGTK.

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

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

В данной работе сравнивался процесс разработки с использованием Tkinter и PyQt.

PyQt – это привязка QT к языку Python. QT содержит множество различных модулей, помимо классов компонентов графического интерфейса. Tkinter же ориентирован исключительно на создание GUI. Tkinter более старая и менее развитая библиотека, однако она включена в стандартную поставку Python для Windows и Mac OS. PyQt и Tkinter – достаточно разные модули и будет интересно их сравнить.

Описание интерфейса и алгоритма работы программы

Программа позволяет пользователю

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

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

Интерфейс приложения, написанный на PyQT

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

Вычисление количества дней между датами производилось с помощью методов модуля datetime, входящего в стандартную поставку интерпретатора Python. Были использованы следующие методы:

  • datetime.date(y, m, d) – создает объект-дату;
  • datetime.timedelta () - создает объект-кол.дней.

С данными объектами можно выполнять перегруженные операции «сложения» и «вычитания».

Разработка программы с использованием PyQt

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

В качестве полей для ввода дат был использован специальный компонент QtGui.QDateEdit, позволяющий вводить дату в указанном формате и заданном диапазоне. Это снимает с программиста проблему обрабатывать корректность ввода пользователем данных. Однако данные из QtGui.QDateEdit возвращаются как объект QtCore.QDate, но с помощью метода toPyDate() их можно преобразовать в тип datetime.date и далее с полученными объектами выполнять вычисления.

Наибольшую сложность при работе с PyQt вызвали менеджеры компоновки (отвечают за размещение компонент в окне). Горизонтальные и вертикальные «упаковщики» (QHBoxLayout, QVBoxLayout) при разработке интерфейса с множеством полей и меток использовать достаточно сложно, т.к. приходится постоянно вкладывать один в другой и это вызывает путаницу. Использовать сетку (QGridLayout) также неудобно, т.к. по умолчанию компонент растягивается на всю ячейку и указанные размеры игнорируются. Настройка сетки с помощью указания дополнительных отступов также неудобна, если компонентов много и часть из них должны занимать несколько ячеек. Поэтому был выбран вариант с абсолютным позиционированием (setGeometry). Однако, как известно, это не лучший выбор, т.к. в разных системах установлены разные шрифты, и интерфейс может искажаться (надпись может выйти за пределы элемента).

Одним из выходов может быть использование QT Designer (дизайнер графического интерфейса) при разработке с использованием PyQt.

Разработка программы с использованием Tkinter

В отличие от PyQt в Tkinter нет специальных полей для ввода даты. Также не удалось найти такой компонент в различных расширениях Tkinter. Оставалось использовать либо обычное текстовое поле (Entry), либо поле для ввода целых чисел в заданном диапазоне (Spinbox). В случае использования Entry пользователь может вводить дату в одном поле. Однако надо запрограммировать «маску» ввода и желательно возможность автоматической подстановки символа-разделителя (между годом, месяцем и датой). Также придется обрабатывать полученную строку и извлекать из нее год, месяц и день. Компонент Spinbox по идее должен был решать часть этих проблем, поэтому было решено использовать его. В результате поле каждой даты состояло из трех компонентов Spinbox [Приложение 2].

Интерфейс приложения, написанный на Tkinter

Однако, как оказалось, несмотря на то, что Spinbox должен позволять вводить только целые числа, пользователь вполне может вписать в это поле букву (клавиатура на ввод буквы не блокируется). Т.е. обработка подобных ситуаций в Tkinter возложена на программиста.

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

В Tkinter как и в PyQt есть три способа размещения компонентов в окне (pack, grid и place). Был выбран метод grid (сетка), настройки которого, на наш взгляд, оказались более продуманными, чем в аналогичном методе из PyQt. Поэтому «спроектировать» внешний вид окна в Tkinter оказалось проще.

Выводы

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

Признак Tkinter PyQt
Назначение Создание графического интерфейса Создание графического интерфейса, работа с базами данных, поддержка svg, видео и др.
Количество компонентов графического интерфейса Ограниченное количество Большая база компонентов, возможность создания собственных компонентов
Требование доработки компонентов со стороны программиста Требуется Не требуется
Универсальность Не подходит для сложных и современных проектов Универсален
Стиль языка Более ясный Достаточно сложный
Скорость разработки PyQt включает Qt Designer позволяющий вести быструю разработку приложений.
Внешний вид компонентов Хуже Лучше
Кроссплатформенность В Windows входит в установочный пакет Python Требуется отдельная установка библиотеки
Размер библиотеки Маленький Большой
Компоновщики Настройки более продуманы. Нельзя сочетать разные в одной программе. Достаточно сложно вручную скомпоновать сложный интерфейс. Зачастую проблема решается с помощью Qt Designer
Документация Мало примеров использования Хорошо документирован

Список использованных источников и литературы

  1. Прохоренок Н. А. Python3 и PyQt. Разработка приложений – СПб.: БХВ-Петербург, 2012. – 704 с.: ил.
  2. Саммерфилд М. «Программирование на Python 3». СПб.: Символ-Плюс, 2009
  3. http://www.pythonware.com/library/tkinter/introduction/index.htm
  4. http://docs.python.org/3/
Прикрепленный файлРазмер
timer_tk.pyw6.69 кб
timer_qt.pyw2.87 кб