![](https://habrastorage.org/getpro/habr/upload_files/d4e/558/51f/d4e55851f8729944c2598b1dbd9972c1.png)
Штош. Наверное, каждый начинающий программист после "Hello, world!" хочет написать какой-нибудь простенький проект. Почти всегда в голову приходит идея создания калькулятора. Но консольный калькулятор - это как-то скучно и просто. Хочется сделать приложение вот прямо как в системе. Ну или хотя бы что-то похожее.
В этой серии статей я научу вас делать простой кроссплатформенный десктопный калькулятор. Здесь не будет тригонометрических функций, процентов, интегралов и других полезных вещей. Вы сможете добавить их по своему желанию.
![](https://habrastorage.org/getpro/habr/upload_files/a6d/abe/542/a6dabe542bd85c6a5edb7d37a185a46c.png)
Мы будем использовать язык Python, фреймворк Qt, библиотеку PySide6, сразу установим её:
pip install PySide6
Qt Designer
Создавать интерфейс мы будем в приложении Qt Designer. Его можно скачать отдельно или найти в папке установленного PySide. Для этого перейдем по пути:
python(или venv*)/Lib/site-packages/PySide6/designer.exe
Создаем Main Window, т.е. главное окно приложения.
![](https://habrastorage.org/getpro/habr/upload_files/8f8/73b/5e4/8f873b5e48a2c0ade555a3bf8083480f.png)
Сразу убираем ненужные menubar и statusbar.
![](https://habrastorage.org/getpro/habr/upload_files/a76/a32/f9e/a76a32f9e82676ebbc128d2b16198594.png)
Название приложения можно изменить в свойстве главного окна windowTitle.
![](https://habrastorage.org/getpro/habr/upload_files/592/e45/73c/592e4573c6adf5b4f6113c328531839f.png)
Элементы калькулятора
Перетащим нужные элементы в интерфейс. В нашем калькуляторе будет поле ввода Line Edit.
![](https://habrastorage.org/getpro/habr/upload_files/b6d/ee1/9b4/b6dee19b4ef70a60fdc83b2c8fb723d5.png)
Label с временным выражением над этим полем ввода.
![](https://habrastorage.org/getpro/habr/upload_files/533/d3a/1ba/533d3a1ba1e318f3e41181ec1989fdd1.png)
Grid Layout для кнопок.
![](https://habrastorage.org/getpro/habr/upload_files/20a/f9e/b2b/20af9eb2b5abc706be4e86bfa6992663.png)
Просто закинем эти элементы и выберем Lay Out Vertically для центрального виджета.
![](https://habrastorage.org/getpro/habr/upload_files/86b/35d/c73/86b35dc7378ce439266289b2f3050f9b.png)
Теперь закинем кнопки в Grid Layout, у меня будет 4 колонки и 5 рядов. Чтобы скопировать и вставить элемент, можно перетащить его с зажатой клавишей Ctrl.
![](https://habrastorage.org/getpro/habr/upload_files/71c/82b/e31/71c82be3181fd3a98b2965502ea33f51.png)
Поставим текст во все кнопки. Для Backspace мы позже поставим иконку.
![](https://habrastorage.org/getpro/habr/upload_files/646/351/94a/64635194a099e66c09c5c4d1475a8319.png)
Проставим горячие клавиши для всех кнопок, кроме Clear и отрицания. За это отвечает свойство shortcut. К сожалению, в Qt Designer нельзя указать несколько горячих клавиш для одной кнопки. Хотелось бы, чтобы клавиши "Enter", "Return" и "=" выполняли вычисление. Мы сделаем это позже в коде. А пока поставим для вычисления одинокую клавишу =.
![](https://habrastorage.org/getpro/habr/upload_files/b85/d6e/4bd/b85d6e4bd45b8e24edb7552c5c76b856.png)
Запишем 0 в Line Edit и выберем правое горизонтальное выравнивание для текста.
![](https://habrastorage.org/getpro/habr/upload_files/903/643/9b1/9036439b1356793faffeccb015ef29aa.png)
Нам нужно сделать так, чтобы пользователь не мог вводить что попало в это поле, чтобы он мог его только читать. Для этого существует свойство readOnly.
![](https://habrastorage.org/getpro/habr/upload_files/a52/1d1/b94/a521d1b94c6c86c6f406367511158c2f.png)
Укажем максимальную длину в 16 символов, как в калькуляторе Windows.
![](https://habrastorage.org/getpro/habr/upload_files/4a0/0ef/24c/4a00ef24ca527f28638ece4b46572273.png)
Запишем в лейбл какое-нибудь выражение и поставим правое выравнивание.
![](https://habrastorage.org/getpro/habr/upload_files/23a/fd4/c41/23afd4c417d06d6d069e36ae63cb5367.png)
Чтобы посмотреть превью дизайна используйте сочетание клавиш Ctrl + R.
![](https://habrastorage.org/getpro/habr/upload_files/b97/fcd/0b1/b97fcd0b10157c4fd50824c1f5c06932.png)
Давайте назовем элементы, чтобы в коде было проще обращаться к ним.
![](https://habrastorage.org/getpro/habr/upload_files/97e/7b9/c50/97e7b9c5006ee91a2cc553beea456c09.png)
Размерная политика элементов
Вы спросите: "Почему интерфейс так плохо выглядит?". Все потому, что у элементов не настроена вертикальная политика. Для лейбла и поля поставим Maximum.
Конечно же не забываем сохранить файл интерфейса. Он имеет расширение ui
. Обычно я называю файл design.ui
![](https://habrastorage.org/getpro/habr/upload_files/65c/e1b/527/65ce1b52785ee42ce9f9865a8cfdcf34.png)
Для всех кнопок поставим Expanding.
![](https://habrastorage.org/getpro/habr/upload_files/563/6f5/ec5/5636f5ec5dac62f42b8ff6dcd5cf728e.png)
Стилизация калькулятора
Сначала нужно определиться с цветовой палитрой. Я буду использовать 4 цвета:
Почти черный
#121212
для фона.Белый
#FFF
для текста кнопок и поля ввода.Серый
#666
для фона кнопок при наведении.Серый посветлее
#888
для текста временного выражения и фона кнопок при нажатии.
В Qt Designer поддерживается язык css. Напишем простенький stylesheet для главного окна. Для всего виджета указываем белый цвет текста и почти черный цвет #121212
для фона.
Я буду использовать бесплатный шрифт Rubik из библиотеки Google Fonts. Он довольно приятный.
QWidget {
color: white;
background-color: #121212;
font-family: Rubik;
font-size: 16pt;
font-weight: 600;
}
Давайте посмотрим, что получается.
![](https://habrastorage.org/getpro/habr/upload_files/d9d/5cb/950/d9d5cb9501d35f809cc35db5526b53f4.png)
![](https://habrastorage.org/getpro/habr/upload_files/010/122/2ad/0101222adadbcf6a1fb573c05d004eef.png)
Давайте изменим кнопки на плоские с прозрачным фоном.
QPushButton {
background-color: transparent;
border: none;
}
Теперь напишем изменение фона кнопок при наведении и нажатии. При наведении цвет фона будет меняться на серый #666
, при нажатии на серый #888.
QPushButton:hover {
background-color: #666;
}
QPushButton:pressed {
background-color: #888;
}
Посмотрим на результат.
![](https://habrastorage.org/getpro/habr/upload_files/3fe/26d/8e8/3fe26d8e8b267cbe4e8347d9c97eb7c2.gif)
Стили для Line Edit и Label
Сначала разберемся с Line Edit. Поставим размер шрифта 40pt
и уберем границы. Я не буду делать какие-то изменения при наведении и нажатии, потому что пользователь не может взаимодействовать с этим полем.
font-size: 40pt;
border: none;
![](https://habrastorage.org/getpro/habr/upload_files/110/d89/ee1/110d89ee14c53ade938d8ec6b8c02944.png)
Для лейбла укажем только цвет #888
. С этим элементом пользователь тоже не может взаимодействовать.
color: #888;
![](https://habrastorage.org/getpro/habr/upload_files/4b0/5b4/f14/4b05b4f14f86062164a1799474f9de2b.png)
Иконки
Теперь зайдем на Google Icons и возьмем черную иконку калькулятора и белую иконку backspace. Я возьму Sharp иконки с размером 24
пикселя. Формат выбирайте на ваше усмотрение. По опыту скажу, что лучше SVG. И лучше оно не только в том, что оно без труда масштабируется без потери качества (векторная графика), но еще и скачивается одним файлом. При скачивании PNG вам нужно будет распаковать архив, зайти в одну из двух папок и вытащить саму иконку.
В статье я скачивал PNG, не делайте так. Я думал, что Qt Designer не поддерживает иконки с векторной графикой, даже не попробовав.
![](https://habrastorage.org/getpro/habr/upload_files/830/31e/064/83031e0647385ee06908fa3c0ca03b26.png)
![](https://habrastorage.org/getpro/habr/upload_files/916/b1f/82b/916b1f82b11a52c1e949fb142b600bf0.png)
Создадим файл ресурсов:
Resource Browser > Edit Resources > New Resource File.
![](https://habrastorage.org/getpro/habr/upload_files/e1b/868/302/e1b8683024be64cab73e87e6d7ea1b8a.png)
![](https://habrastorage.org/getpro/habr/upload_files/9a3/92b/f6c/9a392bf6ce6eeb0e9ef13e5be600438a.png)
Я сохранил файл с названием files.qrc
. Добавим префикс для иконок.
![](https://habrastorage.org/getpro/habr/upload_files/5d6/ee6/d60/5d6ee6d604dd57481dd449c7d17bf262.png)
Закинем туда наши две иконки.
![](https://habrastorage.org/getpro/habr/upload_files/84a/f70/3c3/84af703c3f1703a753ed04ce357fdbcd.png)
Поставим иконку Backspace:
icon > choose Resource
![](https://habrastorage.org/getpro/habr/upload_files/b59/9ba/f26/b599baf26b9fdc5be12b24e30db178b4.png)
Поставим размер 24 x 24
пикселя в свойстве iconSize.
![](https://habrastorage.org/getpro/habr/upload_files/f66/3d6/651/f663d66510c9d3f6513243b7a9a133c9.png)
То же самое проделаем для иконки приложения.
![](https://habrastorage.org/getpro/habr/upload_files/48e/47a/0f9/48e47a0f9f39cd4325639b1c71d6c733.png)
Финальные штрихи
Почти готово. Убираем текст из лейбла. Ставим размер главного окна. У меня будет 300 на 500 пикселей. Такой же размер поставлю минимальным для приложения.
![](https://habrastorage.org/getpro/habr/upload_files/37d/689/597/37d6895977be00569c31d06f49b083c1.png)
Еще добавлю такую фичу - курсор "указывающая рука" для кнопок. Поставлю только для одной кнопки, сейчас доделаем в коде.
![](https://habrastorage.org/getpro/habr/upload_files/af7/29e/d9b/af729ed9bb757b5707d30ae9ccef9f57.png)
![](https://habrastorage.org/getpro/habr/upload_files/a34/c86/9dd/a34c869dd5f84c3c466c0aca4c32f967.gif)
Редактируем интерфейс в коде
Файл интерфейса представляет собой файл с xml разметкой. Мы можем найти блок кода с указывающей рукой, введя в поиске по коду Pointing
![](https://habrastorage.org/getpro/habr/upload_files/8a8/c97/8e5/8a8c978e51db24d89b8e02141e96e748.png)
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
Заметим, что этот блок кода идет после блока размерной политики. Поэтому нам нужно заменить:
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
на:
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
В современных редакторах это сделать очень просто. Например, в VS Code нужно нажать Ctrl + H.
Впишем нужные блоки кода и нажмем Replace All (Ctrl + Alt + Enter).
![](https://habrastorage.org/getpro/habr/upload_files/6a1/567/ffb/6a1567ffbc2b1a686a9fe19a9db0470e.png)
Проверяем в дизайне.
![](https://habrastorage.org/getpro/habr/upload_files/586/09c/dfc/58609cdfc22d0987726926fe099dfbeb.gif)
Дизайн сделан, поздравляю!
Конвертируем файл ресурсов и интерфейса
Для начала нам нужно конвертировать файл ресурсов в питоновский файл. Для этого напишем в терминале:
pyside6-rcc "название файла ресурсов.qrc" > "название файла ресурсов_rc.py"
В нашем случае:
pyside6-rcc files.qrc > files_rc.py
![](https://habrastorage.org/getpro/habr/upload_files/dee/d62/370/deed62370eebfacf08e1c37a8a52e7b8.png)
Теперь конвертируем в Python файл интерфейса. Для этого введем в терминал тот же самый синтаксис, но теперь используем pyside6-uic:
pyside6-uic design.ui > design.py
![](https://habrastorage.org/getpro/habr/upload_files/884/ad4/39d/884ad439d901582065af9038f1d6a3b2.png)
Если у вас на выходе получаются файлы с кодировкой UTF-16
, конвертируйте их в UTF-8
во избежание дальнейших проблем.
![](https://habrastorage.org/getpro/habr/upload_files/8fb/4b4/3f3/8fb4b43f3e597bc213472d8c8999216d.png)
![](https://habrastorage.org/getpro/habr/upload_files/ea9/810/cc4/ea9810cc421fde1fcc1bb632fac2c01a.png)
Штош, в следующей статье напишем код для главного функционала калькулятора. До встречи.