Верстаем интерфейс

Давайте теперь попробуем что-нибудь считать. Сделаем такой мини калькулятор. У которого будет два числа для ввода и возможность сложить их.

Создадим новый проект. Добавим в него пока пустой файлик main.py.

Переключим версию питона на miniconda

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

Теперь давайте запустим pyside6-designer. Тыкаем Ctrl+Shift+P и находим там Python: Создать терминал

снизу откроется консолька, пишем в ней pyside6-designer и жмем enter

в дизайнере тыкаем создать

добавляем два поля для ввода и кнопку

Я хочу выводить ответ прямо на форму. Для этого элемент который называется Label (по-русски: метка, ярлычок, подпись)

давайте теперь всем элементам дадим имена:

  • первое поле для ввода будет txtA
  • второе поле для ввода будет txtB
  • кнопку назовем btnAdd
  • метку для ответа назовем lblAnswer

напоминаю, что, чтобы присвоить элементу имя, надо выбрать его, и справа внизу прописать свойство objectName

Правим верстку

Теперь немного выровняем элементы. Для этого есть такой прием, удерживая Ctrl кликнем последовательно сначала на поля для ввода, а затем на кнопку, вот так:

теперь сверху нажмем на кнопочку с тремя полосками в ряд:

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

Если вы хотите обратно раскидать элементы в произвольном порядке, то тыкнете кнопку с красным значком

но я верну обратно

теперь можно кликнуть где-нибудь в середине формы и нажать еще одну кнопочку:

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

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

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

давайте поменяем текст на кнопке (кликнем на нее два раза):

и чтобы ответ выглядел получше, увеличу шрифт у lblAnswer

Отлично! =) Сохраняем наш результат в папку с проектом под именем MainWindow.ui

проверяем что он появился в Visual Studio Code

Если он там есть, значит все хорошо. Закрываем редактор интерфейсов.

Создаем болванку приложения

И так, у нас есть файл с интерфейсом, сгенерируем по нему python файл, открываем консольку и пишем в ней:

pyside6-uic MainWindow.ui -o mainwindow.py

у нас должен появится файлик mainwindow.py

теперь загоняем в main.py болванку python кода, который запустит наш интерфейс:

import sys
import os
import PySide6
from PySide6.QtWidgets import QApplication, QMainWindow
from mainwindow import Ui_MainWindow

dirname = os.path.dirname(PySide6.__file__)
plugin_path = os.path.join(dirname, 'plugins', 'platforms')
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)


if __name__ == "__main__":
    app = QApplication(sys.argv)

    window = MainWindow()
    window.show()

    sys.exit(app.exec())

попробуем запустить,

если форма появилась и выглядит примерно, как у меня, значит все ок =)

Считываем числа с полей для ввода

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

# ...

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        
        # привязал к событию клика функцию on_btnAdd_clicked
        self.ui.btnAdd.clicked.connect(self.on_btnAdd_clicked)
    
    # собственно сама функция
    def on_btnAdd_clicked(self):
        print("Сложил")

# ...

проверим как оно работает:

отлично, теперь давайте считаем значения с полей, это мы уже делали, правим функцию on_btnAdd_clicked

def on_btnAdd_clicked(self):
    a = self.ui.txtA.text()
    b = self.ui.txtB.text()
    print("Сложил")

попробуем их сложить:

def on_btnAdd_clicked(self):
    a = self.ui.txtA.text()
    b = self.ui.txtB.text()
    print(a + b)

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

def on_btnAdd_clicked(self):
    a = int(self.ui.txtA.text())
    b = int(self.ui.txtB.text())
    print(a + b)

тестируем:

вот теперь другое дело =)

Выводим ответ прямо на форму

Кстати помните мы ж добавляли Label (метку) и даже шрифт ей меняли чтобы выводить в нее ответ. Так давайте ей воспользуемся.

Вывести ответ на форму очень просто, надо вместо функции print воспользоваться функцией setText привязанной к компоненте. Делается это так:

def on_btnAdd_clicked(self):
    a = int(self.ui.txtA.text())
    b = int(self.ui.txtB.text())
    
    self.ui.lblAnswer.setText(f"Сумма: {a + b}")

тестируем:

в принципе и все.

Единственное на что еще важно обратить внимание, что в setText обязательно надо передавать текст. То есть если a и b это числа, то нельзя просто написать

self.ui.lblAnswer.setText(a + b)

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

self.ui.lblAnswer.setText(str(a + b))

либо так

self.ui.lblAnswer.setText(f"{a + b}")

ну либо формировать фразу как мы делали выше.

Вот теперь можно пилить задание =)

Задание

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

чтобы вывести цветное сообщение вы можете использовать html теги. Например так:

self.ui.lblAnswer.setText(f"<b style='color: red'>На ноль делить нельзя</b>")