Содержание

Калькулятор на python / Хабр

Начало

Здравствуйте, в предыдущей статье я показывал как сделать игру на python, а сейчас мы посмотри как сделать простой калькулятор на python tkinter.


Создаём окно 485 на 550. Размеры не важны, мне понравились такие. Так же указываем, что окно не будет изменяться.

from tkinter import *


class Main(Frame):
    def __init__(self, root):
        super(Main, self).__init__(root)
        self.build()

    def build(self):
        pass
 
    def logicalc(self, operation):
        pass

    def update():
       pass


if __name__ == '__main__':
    root = Tk()
    root["bg"] = "#000"
    root.geometry("485x550+200+200")
    root.title("Калькулятор")
    root.resizable(False, False)
    app = Main(root)
    app.pack()
    root.mainloop()

Отлично, идём дальше.


Делаем кнопочки

В методе build создаём такой список:

btns = [
            "C", "DEL", "*", "=",
            "1", "2", "3", "/",
            "4", "5", "6", "+",
            "7", "8", "9", "-",
            "+/-", "0", "%", "X^2"
        ]

Он отвечает за все кнопки, отображающиеся у нас в окне.

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

x = 10
        y = 140
        for bt in btns:
            com = lambda x=bt: self.logicalc(x)
            Button(text=bt, bg="#FFF",
                   font=("Times New Roman", 15),
                   command=com).place(x=x, y=y,
                                      width=115,
                                      height=79)
            x += 117
            if x > 400:
                x = 10
                y += 81

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

self.formula = "0"
self.lbl = Label(text=self.formula, font=("Times New Roman", 21, "bold"),
                 bg="#000", foreground="#FFF")
self.lbl.place(x=11, y=50)

Пишем логику

def logicalc(self, operation):
    if operation == "C":
        self.2":
        self.formula = str((eval(self.formula))**2)
    elif operation == "=":
        self.formula = str(eval(self.formula))
    else:
        if self.formula == "0":
            self.formula = ""
        self.formula += operation
    self.update()

def update(self):
    if self.formula == "":
        self.formula = "0"
    self.lbl.configure(text=self.formula)

Так, как у нас нет ввода с клавиатуры, мы можем позволить себе сделать так, просто проверить на спец. кнопки (C, DEL, =) и в остальных случаях просто добавить это к формуле.

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

Прошу прощения за ошибки в статье. Пишите, я исправлюсь.
from tkinter import *


class Main(Frame):
    def __init__(self, root):
        super(Main, self).__init__(root)
        self.build()

    def build(self):
        self.formula = "0"
        self.lbl = Label(text=self.formula, font=("Times New Roman", 21, "bold"), bg="#000", foreground="#FFF")
        self.2":
            self.formula = str((eval(self.formula))**2)
        elif operation == "=":
            self.formula = str(eval(self.formula))
        else:
            if self.formula == "0":
                self.formula = ""
            self.formula += operation
        self.update()

    def update(self):
        if self.formula == "":
            self.formula = "0"
        self.lbl.configure(text=self.formula)


if __name__ == '__main__':
    root = Tk()
    root["bg"] = "#000"
    root.geometry("485x550+200+200")
    root.title("Калькулятор")
    root.resizable(False, False)
    app = Main(root)
    app.pack()
    root.mainloop()

Калькулятор на Python 3 с графическим интерфейсом — как написать код программы

Многие программисты стараются изучать языки  программирования с помощью написания достаточно простых программ. Один из вариантов – написание калькулятора. Конечно, можно посчитать в отладчике Python или запустив консоль. Но гораздо лучше написать на python свой калькулятор с графическим интерфейсом.

Считаем в консоле

Чтобы посчитать математические выражения можно запустить консоль. Запустить python. После этого набираем математические выражения и получаем ответ. Для этого даже не надо уметь программировать.

Делаем простой калькулятор

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

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

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

В первых строках файла calculator.py подключаем библиотечные функции:

  • Tkinter для графического интерфейса;
  • Decimal для вычислений с большей точность, так как точности float не достаточно.

Импорт библиотек и исходные данные

Создаем окно приложения  — объект Tk с заголовком Calculator. Во вложенном кортеже buttons будут храниться обозначения для кнопок. В список stack будем добавлять введенные числа и операции, которые надо совершить. activeStr предназначен для хранения набираемого числа.

from tkinter import *
from decimal import *

root = Tk()
root.title('Calculator')

buttons = (('7', '8', '9', '/', '4'),
           ('4', '5', '6', '*', '4'),
           ('1', '2', '3', '-', '4'),
           ('0', '.', '=', '+', '4')
           )

activeStr = ''
stack = []

Вычисление результата

Функция calculate получает из списка stack операнды и операцию которую над ними надо произвести. Результат отображается в надписи label. Получать из списка строки будем с помощью метода pop.

def calculate():
    global stack
    global label
    result = 0
    operand2 = Decimal(stack.pop())
    operation = stack.pop()
    operand1 = Decimal(stack.pop())

    if operation == '+':
        result = operand1 + operand2
    if operation == '-':
        result = operand1 - operand2
    if operation == '/':
        result = operand1 / operand2
    if operation == '*':
        result = operand1 * operand2
    label.configure(text=str(result))

Обработка нажатия

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

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

def click(text):
    global activeStr
    global stack
    if text == 'CE':
        stack.clear()
        activeStr = ''
        label.configure(text='0')
    elif '0' <= text <= '9':
        activeStr += text
        label.configure(text=activeStr)
    elif text == '.':
        if activeStr.find('.') == -1:
            activeStr += text
            label.configure(text=activeStr)
    else:
        if len(stack) >= 2:
            stack.append(label['text'])
            calculate()
            stack.clear()
            stack.append(label['text'])
            activeStr = ''
            if text != '=':
                stack.append(text)
        else:
            if text != '=':
                stack.append(label['text'])
                stack.append(text)
                activeStr = ''
                label.configure(text='0')

Внешний вид

Теперь займемся оформлением внешнего вида калькулятора и зададим обработку нажатия кнопок. Создаем надпись для вывода набираемых значений и результатов. В цикле создаем кнопки. Расположение кнопок и надписи осуществляется в табличном виде с помощью упаковщика grid. И в завершении запускаем цикл обработки событий mainloop.

label = Label(root, text='0', width=35)
label.grid(row=0, column=0, columnspan=4, sticky="nsew")

button = Button(root, text='CE', command=lambda text='CE': click(text))
button.grid(row=1, column=3, sticky="nsew")
for row in range(4):
    for col in range(4):
        button = Button(root, text=buttons[row][col],
                command=lambda row=row, col=col: click(buttons[row][col]))
        button.grid(row=row + 2, column=col, sticky="nsew")

root.grid_rowconfigure(6, weight=1)
root.grid_columnconfigure(4, weight=1)

root.mainloop()

У надписи выставлена ширина 35, для того, чтобы оформление кнопок подстраивалось под надпись. И в результате кнопки при этом значении лучше выглядят.

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

 

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

Самый простой калькулятор на Python 3 для новичков

# Создание функции

def main():

    # Выводим сообщение

    print(«Это простой калькулятор на Python»)

    # Запускаем бесконечный цикл

    while True:

        # Выводим сообщение какие действия есть

        print(«Выберите действие которое хотите сделать:\n»

              «Сложить: +\n»

              «Вычесть: -\n»

              «Умножить: *\n»

              «Поделить: /\n»

              «Выйти: q\n»)

        # Переменная для хранения действия

        action = input(«Действие: «)

        # Если action равен q то

        if action == «q»:

            # Выводим сообщение

            print(«Выход из программы»)

            # Выходим из цикла

            break

        # Если action равен +, -, *, /, то

        if action in (‘+’, ‘-‘, ‘*’, ‘/’):

            # Присваиваем значение переменной x

            x = float(input(«x = «))

            # Присваиваем значение переменной y

            y = float(input(«y = «))

            # Если action равен + то

            if action == ‘+’:

                # Выводим сумму x и y

                print(‘%.2f + %.2f = %.2f’ % (x, y, x+y))

            # Если action равен — то

            elif action == ‘-‘:

                # Выводим разность x и y

                print(‘%.2f — %.2f = %.2f’ % (x, y, x-y))

            # Если action равен * то

            elif action == ‘*’:

                # Выводим результат умножения x на y

                print(‘%.2f * %.2f = %.2f’ % (x, y, x*y))

            # Если action равен / то

            elif action == ‘/’:

                # Если y не равен нулю то

                if y != 0:

                    # Выводим результат деления x на y

                    print(‘%.2f / %.2f = %.2f’ % (x, y, x/y))

                else: # Иначе

                    # Выводим сообщение, что на ноль делить нельзя

                    print(«Деление на ноль!»)

Цикл калькулятора в Python 3



Я новичок в программировании и изо всех сил пытаюсь заставить свой код вернуться к началу, чтобы пользователь мог выбрать другую операцию без необходимости перезапуска программы. Я знаю, что очевидный ответ-добавить while loop, но у меня возникли проблемы с реализацией этой стратегии. Я пытался обратиться за помощью, чтобы понять, как лучше всего поступить, чтобы сделать это. Спасибо.

print('Python Calculator Program')
print('         MENU')
print('1)Add')
print('2)Subtract')
print('3)Multiply')
print('4)Divide')
print('5)Square Root')
print('6)Exit')


print('Enter Your Choice:')
operator=input('Choose a number 1 - 6: ')


while True:
    if operator == '1' or operator == 'Add' or operator == 'add':
        a=float(input('Enter the fist number that you wish to add: '))
        b=float(input('Enter the second number that you wish to add: '))

        ans=sum(a,b)
        print('The sum of the numbers are: ', ans)

    elif operator == '2' or operator == 'Subtract' or operator == 'subtract':
        a=float(input('Enter the fist number that you wish to subtract: '))
        b=float(input('Enter the second number that you wish to subtract: '))

        ans=difference(a,b)
        print('The difference of the numbers are: ', ans)

    elif operator == '3' or operator == 'Multiply' or operator == 'multiply':
        a=float(input('Enter the fist number that you wish to multiply: '))
        b=float(input('Enter the second number that you wish to multiply: '))

        ans=product(a,b)
        print('The product of the numbers are: ', ans)

    elif operator == '4' or operator == 'Divide'  or operator == 'divide':
        a=float(input('Enter the dividend: '))
        b=float(input('Enter the divisor: '))

        ans=quotient(a,b)
        print('The quotient of the numbers are: ', ans)

    elif operator == '5' or operator == 'Square Root' or operator == 'sqaure root':
        a=float(input('Enter the number you wish to find the square root of: '))

        ans=sqrt(a)
        print('The square root of the number is: ', ans)

    elif operator =='6':
        print('CALCULATOR: ON [OFF]')
        break


    else:
        print('Enter the math operator as dislayed')
        operator=input('Choose an operator: ')





def sum(a,b):
    return a+b

def difference(a,b):
    return a-b

def product(a,b):
    return a*b

def quotient(a,b):
    return a/b

def sqrt(a):
    import math
    return(math.sqrt(a))

main()
python loops while-loop
Поделиться Источник Ron Estrada     13 февраля 2019 в 20:10

3 ответа


  • Моя программа калькулятора в Python позволяет вводить символы

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

  • Python код калькулятора не работает

    Недавно у меня появился raspberry pi, и я учусь кодировать на python, используя его. У меня также есть руководство пользователя raspberry, и я копирую сценарий калькулятора, но он не работает, не могли бы вы помочь??? это мой сценарий; username = raw_input(What is your name? ) print (Welcome to…



1

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

import math

def sum(a,b): return a+b

def difference(a,b): return a-b

def product(a,b): return a*b

def quotient(a,b): return a/b

def sqrt(a): return(math.sqrt(a))

def selectMenu():
    print('Python Calculator Program')
    print('         MENU')
    print('1)Add')
    print('2)Subtract')
    print('3)Multiply')
    print('4)Divide')
    print('5)Square Root')
    print('6)Exit')
    print('Enter Your Choice:')
    return input('Choose a number 1 - 6: ')


def main():
ans = "" #declare ans because if we try to see if ans == "" and ans doesnt exist, the 
         #program will crash
operator = "" # "" is not 6, therefore the while loop will run at least once
while operator != '6': #as long as the variable operator is not 6  // operator != '6' 
                       #is your condition
    operator = selectMenu() #this will get the user's choice
    operation = "" #our placeholder for the operation string
    if operator == '1' or operator.lower() == 'add': #.lower() will convert the 
                                                     #entire string to lowercase, so 
                                                     #that you dont have to test for                                                          
                                                     #caps
        a=float(input('Enter the fist number that you wish to add: '))
        b=float(input('Enter the second number that you wish to add: '))
        operation = "sum"
        ans= sum(a,b)

    elif operator == '2' or operator.lower() == 'subtract':
        a=float(input('Enter the fist number that you wish to subtract: '))
        b=float(input('Enter the second number that you wish to subtract: '))
        operation = "difference"
        ans = difference(a, b)


    elif operator == '3' or operator.lower() == 'multiply':
        a=float(input('Enter the fist number that you wish to multiply: '))
        b=float(input('Enter the second number that you wish to multiply: '))
        operation = "product"
        ans=product(a,b)

    elif operator == '4' or operator.lower() == 'divide':
        a=float(input('Enter the dividend: '))
        b=float(input('Enter the divisor: '))
        operation = "quotient"
        ans=quotient(a,b)


    elif operator == '5' or operator.lower() == 'square root':
        a=float(input('Enter the number you wish to find the square root of: '))
        operation = "square root"
        ans=sqrt(a)

    elif operator =='6':
       print('CALCULATOR: ON [OFF]')
       operation = ""
       ans = ""
       #break // while break technically works, its a bad habit to get in to. your 
       #loops should naturally terminate themselves by causing the condition to 
       #become false

    else:
        print('Enter the math operator as displayed')

         if ans != "": # since we're always gonna print the answer no matter what 
                       #they pick, its easier to do it after your if statements.
             print() #print empty lines for spacing
             print("The ", operation, " is: ", ans)
             print()

 main()

Поделиться Grimmpier     13 февраля 2019 в 21:06



1

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

while True:
    operator=input('Choose a number 1 - 6: ')
    if operator == '1' or operator == 'Add' or operator == 'add':
..... # all your other code

Поделиться Reedinationer     13 февраля 2019 в 20:18



0

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

надеюсь, это поможет

import math



def isfloat(value):
  """
    Checks if the given value represent float
  :param value:
  :return: True if float
  """
  try:
    float(value)
    return True
  except:
    return False



def chooseOperator(input):
    # Returns a method to run
    return {

        '1': oneAdd,
        'add': oneAdd,
        '2': twoDif,
        'subtract': twoDif,
        '3': threeMult,
        'multiply': threeMult,
        '4': fourDiv,
        'divide': fourDiv,
        '5': fiveSqrt,
        'sqaure root': fiveSqrt,
        '6': sixExit,
        'exit': sixExit

    }[input]


def printMenu():
    print('\n\t--  MENU  --')
    print('1)\t Add')
    print('2)\t Subtract')
    print('3)\t Multiply')
    print('4)\t Divide')
    print('5)\t Square Root')
    print('6)\t Exit')




def mainLoop():
    inputFromUser = True
    print('\n\n**   Python Calculator Program   **')
    print('CALCULATOR: [ON] OFF')


    while inputFromUser:
        # Prints the menu to the console
        printMenu()

        try:
            # operator is a function
            operator = chooseOperator((input('Choose an operator:  ')).lower())
            # inputFromUser is a boolean variable
            inputFromUser = operator()

        except KeyError:
            # Unknown input
            print('\n\t Please choose an operator from the menu')




def oneAdd():
    # Get input from user
    a = input('Enter the first number that you wish to add: ')
    b = input('Enter the second number that you wish to add: ')

    # Check that the input is valid
    if isfloat(a) and isfloat(b):
        # Calculate with values
        ans = float(a) + float(b)
        print('The sum of the numbers are: ', ans)


    else:
        # Notify the user that the values are not valid
        print("\tInvalid values:")
        print("\t\tfirst  = ", a)
        print("\t\tsecond = ", b)

    return True


def twoDif():
    # Get input from user
    a = input('Enter the first number that you wish to subtract: ')
    b = input('Enter the second number that you wish to subtract: ')

    # Check that the input is valid
    if isfloat(a) and isfloat(b):
        # Calculate with values
        ans = float(a) - float(b)
        print('The difference of the numbers are: ', ans)


    else:
        # Notify the user that the values are not valid
        print("\tInvalid values:")
        print("\t\tfirst  = ", a)
        print("\t\tsecond = ", b)


    return True


def threeMult():
    # Get input from user
    a = input('Enter the first number that you wish to multiply: ')
    b = input('Enter the second number that you wish to multiply: ')

    # Check that the input is valid
    if isfloat(a) and isfloat(b):
        # Calculate with values
        ans = float(a) * float(b)
        print('The product of the numbers are: ', ans)

    else:
        # Notify the user that the values are not valid
        print("\tInvalid values:")
        print("\t\tfirst  = ", a)
        print("\t\tsecond = ", b)

    return True


def fourDiv():
    # Get input from user
    a = input('Enter the dividend: ')
    b = input('Enter the divisor: ')

    # Check that the input is valid
    if isfloat(a) and isfloat(b):
        # Calculate with values
        ans = float(a) / float(b)
        print('The quotient of the numbers are: ', ans)

    else:
        # Notify the user that the values are not valid
        print("\tInvalid values:")
        print("\t\tfirst  = ", a)
        print("\t\tsecond = ", b)

    return True


def fiveSqrt():
    # Get input from user
    a = input('Enter the number you wish to find the square root of: ')

    # Check that the input is valid
    if isfloat(a):
        # Calculate with values
        ans = math.sqrt(float(a))
        print('The square root of the number is: ', ans)

    else:
        # Notify the user that the values are not valid
        print("\tInvalid value:")
        print("\t\tfirst  = ", a)

    return True


def sixExit():
    print('\n\nCALCULATOR: ON [OFF]')
    return False





if __name__ == '__main__':

    mainLoop()

Поделиться Yonatan Zax     13 февраля 2019 в 21:24


  • Базовая программа калькулятора не работает в режиме ожидания Python

    loop = 1 choice = 0 #holds the user choice for menu while (loop == 1): print (Welcome to calci.py) print (your options are:) print ( ) print (1. Addition) print (2. Subtraction) print (3. Multiplication) print (4. Division) print (5. Quit calculator.py) print ( ) choice = input(Choose your option:…

  • Выпуск калькулятора чаевых

    пытаясь написать код python для калькулятора чаевых на основе сервиса, я столкнулся с проблемой с моим while loop. service = while service != excellent or service != good or service != bad: service = input((Please choose excellent, good, or bad): ) Эта часть вызывает бесконечный цикл, но я не…


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


Создание калькулятора в python

Поэтому я попытался использовать этот кусок кода для создания калькулятора в python, так как я только начал учиться. Дело в том, что он всегда говорит, что я ввожу недопустимый вариант, проходя…


Базовая программа калькулятора в python

Я только что написал простой скрипт калькулятора в python, как правило, python должен распознавать знак ( — ) минус, (*) умножение, (/) деление по умолчанию, но при рассмотрении этого скрипта он не…


Цикл калькулятора в Python

Нужно добавить цикл в мой калькулятор, предоставив пользователю возможность перезапустить калькулятор, поместив код в while loop с условием, что ввод от пользователя должен быть ‘y’ или ‘Y’. def…


Моя программа калькулятора в Python позволяет вводить символы

Я создал программу калькулятора в Python, используя Tkinter, и она работает полностью; но когда я запускаю ее, вы можете нажать на поле ввода в верхней части моего калькулятора и ввести символы. Я…


Python код калькулятора не работает

Недавно у меня появился raspberry pi, и я учусь кодировать на python, используя его. У меня также есть руководство пользователя raspberry, и я копирую сценарий калькулятора, но он не работает, не…


Базовая программа калькулятора не работает в режиме ожидания Python

loop = 1 choice = 0 #holds the user choice for menu while (loop == 1): print (Welcome to calci.py) print (your options are:) print ( ) print (1. Addition) print (2. Subtraction) print (3….


Выпуск калькулятора чаевых

пытаясь написать код python для калькулятора чаевых на основе сервиса, я столкнулся с проблемой с моим while loop. service = while service != excellent or service != good or service != bad: service…


Что такое режим калькулятора?

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


python 3 не работает

В частности, я получаю ошибку типа, которая говорит, что функция pow() не принимает строки или целые числа? Я следую кодовому символу для целого числа с этого сайта…


Самая короткая программа калькулятора в python году

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

Создание Калькулятора В Python

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

def add(num1, num2):
return num1 + num2
def sub(num1, num2):
return num1 - num2
def mult(num1, num2):
return num1 * num2
def div(num1, num2):
return num1 / num2

def main():
operation = raw_input('\n' "What do you want to do? (+, -, *, /): ")

if (operation != '+' and operation != '-' and operation != '*' and operation != '/'):
print("Please enter a valid operation")
else:
while True:
try:
var1 = float(raw_input("Enter num1: "))
var2 = float(raw_input("Enter num2: "))
except ValueError:
print('\n' "Please enter numbers only")
continue
else:
break
print('\n' "The answer is:")
if(operation == '+'):
print(add(var1, var2))
if(operation == '-'):
print(sub(var1, var2))
if(operation == '*'):
print(mult(var1, var2))
if(operation == '/'):
try:
print(div(var1, var2))
except ZeroDivisionError:
print("Infinity!")
while True:
main()

Вывод:

Что ты хочешь делать? (+, -, *,/): +

Введите num1: 6

Введите num2: 4

Ответ:

10,0

Что ты хочешь делать? (+, -, *,/): r

Введите действительную операцию

Что ты хочешь делать? (+, -,/):

Введите num1: 1

Введите num2: e

Пожалуйста, введите только цифры

Введите num1: t

Пожалуйста, введите только цифры

Введите num1: 2.345

Введите num2: 4.67

Ответ:

10,95115

Что ты хочешь делать? (+, -, *,/): /

Введите num1: 4

Введите num2: 0

Ответ:

Бесконечность!

Что ты хочешь делать? (+, -, *,/):

Базовая программа калькулятор с использованием Python

  

def add(num1, num2):

    return num1 + num2

  

def subtract(num1, num2):

    return num1 - num2

  

def multiply(num1, num2):

    return num1 * num2

  

def divide(num1, num2):

    return num1 / num2

  

print("Please select operation -\n" \

        "1. Add\n" \

        "2. Subtract\n" \

        "3. Multiply\n" \

        "4. Divide\n")

  

  

select = input("Select operations form 1, 2, 3, 4 :")

  

number_1 = int(input("Enter first number: "))

number_2 = int(input("Enter second number: "))

  

if select == '1':

    print(number_1, "+", number_2, "=",

                    add(number_1, number_2))

  

elif select == '2':

    print(number_1, "-", number_2, "=",

                    subtract(number_1, number_2))

  

elif select == '3':

    print(number_1, "*", number_2, "=",

                    multiply(number_1, number_2))

  

elif select == '4':

    print(number_1, "/", number_2, "=",

                    divide(number_1, number_2))

else:

    print("Invalid input")

Как создать калькулятор на Питоне?

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


Создайте простой калькулятор, который считывает из строки ввода три строки: 1-ое число, 2-ое число и операцию, после чего применяет операцию к введённым числам («первое число» «операция» «второе число»), а затем выводит результат на экран.


Калькулятор должен поддерживать следующие операции: +, -, /, *, mod, pow, div

,где

  • mod — это взятие остатка от деления,
  • pow — возведение в степень,
  • div — целочисленное деление.

Если выполняется деление и второе число равно 0, необходимо выводить строку «Деление на 0!».

На вход программы нужно подавать вещественные числа!

Код программы Калькулятор

x=float(input("Введите значение x ="))
y=float(input("Введите значение y ="))
z=input("Введите оператор (+, -, /, *, mod, pow, div) =")
if z==+:
result=x+y
elif z==-:
result=x-y
elif z==pow:
result=pow(x,y)
elif z==*:
result=x*y
elif y!=0:
if z==/:
result=x/y
elif z==div:
result=x//y
elif z==mod:
result=x%y
elif y==0:
result="Деление на 0!"
print("Результат вычислений =",result)

Необходимость создания подуровня для операторов ветвления обусловлена тем, что все вычисления, связанные с делением не имеет смысла проводить, если второе число будет равно нулю.

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

elif y==0:  
result="Деление на 0!"

Примеры результатов вычислений программы

Python 3.5.2 (default, Dec 2015, 13:05:11)
[GCC 4.8.2] on linux

Введите значение x = 12
Введите значение y = 12
Введите оператор (+, -, /, *, mod, pow, div) = pow
Результат вычислений = 8916100448256


Создание игры на Питоне. «Угадай число»

Базовая программа калькулятора с использованием Python

по умолчанию добавить (число1, число2):

возврат число1 + число2

по умолчанию вычитание (число1, число2):

возврат число1 - число2

по умолчанию умножить (число1, число2):

возврат число1 * число2

по умолчанию деление (число1, число2):

возврат число1 / число2

печать ( "Выберите операцию - \ n" \

"1.Добавить \ n " \

"2. Вычесть \ n" \

"3. Умножение \ n" \

"4. Разделить \ n" )

выбор = int ( вход ( "Выбор формы операций 1, 2, 3, 4:" ))

число_1 = int ( ввод ( "Введите первое число:" ))

число_2 = int ( ввод ( "Введите второе число:" ))

если выберите = = 1 :

печать (число_1, "+" , число_2, "=" ,

доб. (Число_1, число_2))

elif выберите = = 2 :

печать (число_1, "-" , число_2, "=" ,

вычесть (число_1, число_2))

elif выберите = = 3 :

печать (число_1, "*" , число_2, "=" ,

умножить (число_1, число_2))

elif выберите = = 4 :

печать (число_1, "/" , число_2, "=" ,

разделить (число_1, число_2))

еще :

печать ( «Недействительный ввод» )

3 способа написать калькулятор на Python | Джейми Баллок

Калькуляторы Python: хорошее и плохое.и уродливый

Фото StellrWeb на Unsplash

Известно, согласно Дао Python, для любой конкретной задачи:

Должен быть один — и желательно только один — очевидный способ сделать это

Однако в случае Чтобы написать простую программу-калькулятор, есть много разных способов сделать это. Какой из них «лучший», во многом зависит от контекста.

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

Решение 1. Условное ветвление

Я предполагаю, что если бы существовал единственный «очевидный» способ построить калькулятор на Python, это было бы использование условного ветвления.

Основные шаги:

  1. Спросить пользователя о вводе
  2. Условно выбрать операцию на основе выбранного оператора
  3. Выполнить расчет с использованием выбранного оператора
  4. Распечатать результат

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

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

В зависимости от того, чего вы пытаетесь достичь, могут быть лучшие решения.

Вот ссылка на рабочий код.

Решение 2: eval ()

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

Используя это, приведенный выше код можно уменьшить до:

 calc = input ("Расчет типа: \ n") 

print ("Ответ:" + str (eval (calc)))

eval () имеет некоторые преимущества по сравнению с решением 1:

  • Он может принимать произвольные выражения (например,грамм. 1 + 2-3 * 4 ) не только бинарные операции
  • Значительно меньше кода

Вот ссылка на рабочий код.

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

Хорошую статью о рисках безопасности eval можно найти здесь.

Решение 3. Поиск по словарю и рекурсия

В этой версии калькулятора Python мы сделаем следующие улучшения по сравнению с решением 1:

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

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

Этот подход более эффективен, чем решение 1, и более безопасен, чем решение 2.

Принцип работы таков: когда пользователь передает строку (например, 1 + 2 * 3), наша функция calculate () выполняет итерацию по каждому оператору, который мы определили в словаре операторов , и вызывает раздел строки. при первом появлении этого оператора. В случае 1 + 2 * 3 это даст нам:

 left = '1' 
operator = '+'
right = '2 * 3'

calculate () затем вызывается рекурсивно на подвыражения до с.isdigit () возвращает истину. Итак, в приведенном выше примере наш рекурсивный вызов будет выглядеть так:

 операторов возврата ['+'] (вычислить ('1'), вычислить ('2 * 3')) 

Что разрешает:

 return add (1, 6) 

Если бы я писал «реальный» калькулятор на Python, я бы взял что-то вроде этого в качестве отправной точки.

Вот ссылка на рабочий код.

Бонусное решение: электронный модуль!

Последний «бонусный» подход и, возможно, мой любимый - это использование превосходного электронного модуля.Благодаря этому мы можем оценивать выражения Python «напрямую» из командной строки , не открывая интерпретатор Python .

Для установки:

 pip install e 

Затем, чтобы использовать, мы можем просто написать:

 $ python -me 1 + 1 
2 $ python -me "10 * 5 - (6 ** 2) + 6 / 3 "
16

Очень удобно!

Программа калькулятора на Python - AskPython

Программирование на Python

- отличный инструмент для оценки и выполнения манипуляций. В этой статье мы изучим простую программу-калькулятор командной строки на Python 3.

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

Предварительные требования

В системе должен быть установлен Python 3 на локальном компьютере и на нем должна быть настроена среда программирования.


Принять / запросить ввод от пользователя

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

num_1 = input ('Введите свой первый номер:')
num_2 = input ('Введите второе число:')
 

Выход :

Введите свой первый номер: 10
Введите свой второй номер: 5
 

Мы должны сохранить программу перед ее запуском. Вы должны иметь возможность вводить текст в окне терминала в ответ на каждое приглашение.


Определение и использование операторов

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

num_1 = int (input ('Введите первое число:'))
num_2 = int (input ('Введите второе число:'))

# Добавление
print ('{} + {} =' .format (число_1, число_2))
печать (число_1 + число_2)

# Вычитание
print ('{} - {} =' .format (число_1, число_2))
печать (число_1 - число_2)

# Умножение
print ('{} * {} =' .format (число_1, число_2))
печать (число_1 * число_2)

# Разделение
print ('{} / {} =' .format (число_1, число_2))
печать (число_1 / число_2)
# Формат () поможет улучшить внешний вид вывода и его форматирование.
 

Выход :

Введите свой первый номер: 15
Введите ваше второе число: 10
15 + 10 =
25
15 - 10 =
05
15 * 10 =
150
15/10 =
1.5
 

Если вы посмотрите на вышеприведенный вывод, мы можем заметить, что как только пользователь вводит num_1 как 15 и num_2 как 10 , все операции калькулятора выполняются.

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


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

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

выбор = вход ('' '
Пожалуйста, выберите тип операции, которую вы хотите выполнить:
+ для сложения
- на вычитание
* для умножения
/ для деления
'' ')

num_1 = int (input ('Введите первое число:'))
num_2 = int (input ('Введите второе число:'))

если выбор == '+':
    print ('{} + {} =' .format (число_1, число_2))
    печать (число_1 + число_2)

elif choice == '-':
    print ('{} - {} =' .format (число_1, число_2))
    печать (число_1 - число_2)

elif choice == '*':
    print ('{} * {} =' .format (число_1, число_2))
    печать (число_1 * число_2)

elif choice == '/':
    print ('{} / {} ='.формат (число_1, число_2))
    печать (число_1 / число_2)

еще:
    print ('Введите допустимый оператор, запустите программу еще раз.')
 

Выход :

Пожалуйста, выберите тип операции, которую вы хотите выполнить:
+ для сложения
- на вычитание
* для умножения
/ для деления

*

Пожалуйста, введите первое число: 10
Пожалуйста, введите второе число: 40
10 * 40 =
400
 

Список литературы

Как создать простой калькулятор с использованием Python

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

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

Вот как будет выглядеть калькулятор:

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

Вы можете запустить следующий код в Python, чтобы запустить калькулятор:

 импорт tkinter as tk

корень = тк.Тк ()

canvas1 = tk.Canvas (корень, ширина = 300, высота = 300)
canvas1.pack ()

entry1 = tk.Entry (корень)
canvas1.create_window (210, 100, окно = запись1)

entry2 = tk.Entry (корень)
canvas1.create_window (210, 140, окно = запись2)

entry3 = tk.Entry (корень)
canvas1.create_window (210, 240, окно = запись3)

label0 = tk.Label (корень, текст = 'Калькулятор')
label0.config (font = ('helvetica', 14))
canvas1.create_window (150, 40, окно = label0)

label1 = tk.Метка (корень, текст = 'Значение типа 1:')
label1.config (font = ('helvetica', 10))
canvas1.create_window (100, 100, окно = label1)

label2 = tk.Label (root, text = 'Значение типа 2:')
label2.config (font = ('helvetica', 10))
canvas1.create_window (100, 140, окно = label2)

label3 = tk.Label (root, text = 'Результат:')
label3.config (font = ('helvetica', 10))
canvas1.create_window (100, 240, окно = label3)

def add ():
    v1 = entry1.get ()
    v2 = entry2.get ()
  
    label4 = tk.Метка (корень, текст = float (v1) + float (v2), font = ('helvetica', 10, 'bold'), bg = 'white')
    canvas1.create_window (210, 240, окно = label4)
      
buttonAdd = tk.Button (text = '+', command = add, bg = 'green', fg = 'white', font = ('helvetica', 9, 'жирный'), width = 5)
canvas1.create_window (90, 190, окно = buttonAdd)

def sub ():
    v1 = entry1.get ()
    v2 = entry2.get ()
  
    label5 = tk.Label (root, text = float (v1) -float (v2), font = ('helvetica', 10, 'bold'), bg = 'white')
    холст1.create_window (210, 240, окно = label5)
      
buttonSub = tk.Button (text = '-', command = sub, bg = 'green', fg = 'white', font = ('helvetica', 9, 'bold'), width = 5).
canvas1.create_window (140, 190, окно = buttonSub)

def mul ():
    v1 = entry1.get ()
    v2 = entry2.get ()
  
    label6 = tk.Label (root, text = float (v1) * float (v2), font = ('helvetica', 10, 'bold'), bg = 'white')
    canvas1.create_window (210, 240, окно = label6)
      
buttonMul = tk.Button (text = 'x', command = mul, bg = 'green', fg = 'white', font = ('helvetica', 9, 'жирный'), width = 5)
холст1.create_window (190, 190, окно = buttonMul)

def div ():
    v1 = entry1.get ()
    v2 = entry2.get ()
  
    label7 = tk.Label (корень, текст = float (v1) / float (v2), font = ('helvetica', 10, 'bold'), bg = 'white')
    canvas1.create_window (210, 240, окно = label7)
      
buttonDiv = tk.Button (text = '/', command = div, bg = 'green', fg = 'white', font = ('helvetica', 9, 'bold'), width = 5).
canvas1.create_window (240, 190, окно = buttonDiv)

root.mainloop ()
 

Использование калькулятора в Python

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

Допустим, вы хотите просуммировать значения 4 и 3.Затем вы можете ввести эти значения в поля ввода, а затем нажать кнопку «+», чтобы добавить эти значения:

В результате вы получите 7 . Что на самом деле является суммой 4 и 3:

И если вы решите вместо этого умножить эти значения, просто нажмите «x», чтобы умножить значения, и вы получите результат 12 :

В последнем разделе я объясню каждый компонент, который использовался в коде.

Как собрать калькулятор на Python

Импортируйте пакет tkinter и создайте Canvas

Первое, что вам нужно сделать, это импортировать пакет tkinter .Пакет tkinter можно использовать для создания графического интерфейса пользователя (GUI) в Python.

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

 импорт tkinter as tk

корень = tk.Tk ()

canvas1 = tk.Canvas (корень, ширина = 300, высота = 300)
canvas1.pack ()
 

Создайте поля ввода

Затем вам нужно будет создать поля ввода для сбора данных от пользователя.

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

 entry1 = tk.Entry (корень)
canvas1.create_window (210, 100, окно = запись1)

entry2 = tk.Entry (корень)
canvas1.create_window (210, 140, окно = запись2)

entry3 = tk.Entry (корень)
canvas1.create_window (210, 240, окно = запись3)
 

Добавьте метки

В настоящее время в графическом интерфейсе отображаются 4 метки:

  • Калькулятор
  • Значение типа 1:
  • Значение типа 2:
  • Результат:

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

 label0 = tk.Label (root, text = 'Calculator')
label0.config (font = ('helvetica', 14))
canvas1.create_window (150, 40, окно = label0)

label1 = tk.Label (root, text = 'Значение типа 1:')
label1.config (font = ('helvetica', 10))
canvas1.create_window (100, 100, окно = label1)

label2 = tk.Label (root, text = 'Значение типа 2:')
label2.config (font = ('helvetica', 10))
canvas1.create_window (100, 140, окно = label2)

label3 = tk.Label (root, text = 'Результат:')
label3.config (font = ('helvetica', 10))
canvas1.create_window (100, 240, окно = label3)
 

Создание функций и кнопок

В коде 4 функции:

  • добавить - для сложения значений
  • sub - для вычитания значений
  • mul - для умножения значений
  • div - для разделения значений

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

 def add ():
    v1 = entry1.get ()
    v2 = entry2.get ()
  
    label4 = tk.Label (корень, текст = float (v1) + float (v2), font = ('helvetica', 10, 'bold'), bg = 'white')
    canvas1.create_window (210, 240, окно = label4)
      
buttonAdd = tk.Button (text = '+', command = add, bg = 'green', fg = 'white', font = ('helvetica', 9, 'жирный'), width = 5)
холст1.create_window (90, 190, окно = buttonAdd)

def sub ():
    v1 = entry1.get ()
    v2 = entry2.get ()
  
    label5 = tk.Label (root, text = float (v1) -float (v2), font = ('helvetica', 10, 'bold'), bg = 'white')
    canvas1.create_window (210, 240, окно = label5)
      
buttonSub = tk.Button (text = '-', command = sub, bg = 'green', fg = 'white', font = ('helvetica', 9, 'bold'), width = 5).
canvas1.create_window (140, 190, окно = buttonSub)

def mul ():
    v1 = запись1.получать()
    v2 = entry2.get ()
  
    label6 = tk.Label (root, text = float (v1) * float (v2), font = ('helvetica', 10, 'bold'), bg = 'white')
    canvas1.create_window (210, 240, окно = label6)
      
buttonMul = tk.Button (text = 'x', command = mul, bg = 'green', fg = 'white', font = ('helvetica', 9, 'жирный'), width = 5)
canvas1.create_window (190, 190, окно = buttonMul)

def div ():
    v1 = entry1.get ()
    v2 = entry2.get ()
  
    label7 = tk.Label (корень, текст = float (v1) / float (v2), font = ('helvetica', 10, 'bold'), bg = 'white')
    холст1.create_window (210, 240, окно = label7)
      
buttonDiv = tk.Button (text = '/', command = div, bg = 'green', fg = 'white', font = ('helvetica', 9, 'bold'), width = 5).
canvas1.create_window (240, 190, окно = buttonDiv)

root.mainloop ()
 

Не забудьте добавить root.mainloop () в конце.

Программа Python для создания простого калькулятора

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

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

Функции Python
Аргументы функций Python
Пользовательские функции Python

Исходный код: Простой Caculator путем создания функций

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

# Эта функция складывает два числа
def add (x, y):
return x + y

# Эта функция вычитает два числа
def subtract (x, y):
return x - y

# Эта функция умножает два числа
def multiply (x, y):
return x * y

# Эта функция делит два числа
def div (x, y):
return x / y

print («Выбрать операцию.")
print (" 1.Add ")
print (" 2.Subtract ")
print (" 3.Multiply ")
print (" 4.Divide ")

# Принять ввод от пользователя
choice = input ("Введите выбор (1/2/3/4):")

num1 = int (input ("Введите первое число:"))
num2 = int (input ("Введите второе число:"))

если choice == '1':
print (num1, "+", num2, "=", add (num1, num2))

elif choice == '2':
print (num1, "-", num2, "=", вычесть (num1, num2))

elif choice == '3':
print (num1, "*", num2, "=", multiply (num1, num2))

elif choice == ' 4 ':
print (num1, "/", num2, "=", div (num1, num2))
else:
print ("Недопустимый ввод")

Вывод

Выберите операцию.
1. Сложить
2. Вычесть
3. Умножить
4. Разделить
Введите выбор (1/2/3/4): 3
Введите первое число: 15
Введите второе число: 14
15 * 14 = 210

В этой программе мы просим пользователя выбрать желаемую операцию. Возможны варианты 1, 2, 3 и 4. Берутся два числа, и ветвление if ... elif ... else используется для выполнения определенного раздела. Пользовательские функции add (), subtract (), multiply () и diver () оценивают соответствующие операции.

новичок - Простой калькулятор на Python

Для новичка это неплохо.Но с этим связаны три вопиющие проблемы.

  1. Вам следует использовать «главную» функцию.
  2. Вам следует использовать словарь.
  3. оператора

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

Определить одно довольно просто, и его использование уменьшит объем кода.

  операторов = {
    "+": добавить,
    "-": sub,
    "*": муль,
    "/": div,
    "pow": pow
}
  

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

  func = operator.get (оператор, Нет)
если func равно None:
    print ("Неверный оператор!")
    Продолжить
  

Красиво и просто.

Основная функция проста, просто переместите все в , если __name__ == '__main__': в функцию. С добавлением оператора вам действительно не нужно делать меньшие функции, но это может быть хорошей идеей, создание функции для получения пользовательского ввода может быть хорошей идеей.Но решать только вам. Если бы вы действительно хотели сделать и то, и другое, вы бы сделали что-то вроде:

  def main ():
    в то время как True:
        число1, число2, оператор = get_user_input ()
        func = operator.get (оператор, Нет)
        если func равно None:
            print ("Неверный оператор!")
            Продолжить

        print (func (число1; число2))

если __name__ == '__main__':
    главный()
  

Следует отметить, что вы можете не захотеть делать get_user_input .

Вы можете не знать, что можете использовать встроенную библиотеку операторов.Это позволит вам удалить все ваши определения , добавить , sub и т. Д. И позволит вам сменить операторов на:

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

операторы = {
    «+»: operator.add,
    «-»: operator.sub,
    "*": operator.mul,
    "/": operator.truediv,
    "pow": operator.pow
}
  

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

Создание настольного калькулятора с графическим интерфейсом пользователя - Real Python

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

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

Понимание PyQt

PyQt - это привязка Python для Qt , которая представляет собой набор библиотек C ++ и инструментов разработки, которые включают платформо-независимые абстракции для графических пользовательских интерфейсов (GUI), а также сети, потоки, регулярные выражения, базы данных SQL, SVG, OpenGL, XML и многие другие мощные функции.PyQt, разработанный RiverBank Computing Ltd, доступен в двух редакциях:

.
  1. PyQt4: выпуск, созданный для Qt 4.x и 5.x
  2. PyQt5: выпуск, созданный только для Qt 5.x

Несмотря на то, что PyQt4 может быть построен против Qt 5.x, будет поддерживаться только небольшое подмножество, которое также совместимо с Qt 4.x. Это означает, что если вы решите использовать PyQt4, то, вероятно, упустите некоторые новые функции и улучшения в PyQt5.См. Документацию PyQt4 для получения дополнительной информации по этой теме.

В этом руководстве вы расскажете о PyQt5, поскольку, похоже, это будущее библиотеки. С этого момента не забудьте рассматривать любое упоминание PyQt как ссылку на PyQt5.

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

PyQt5 основан на Qt v5 и включает классы, которые охватывают графические пользовательские интерфейсы, а также обработку XML, сетевое взаимодействие, регулярные выражения, потоки, базы данных SQL, мультимедиа, просмотр веб-страниц и другие технологии, доступные в Qt.PyQt5 реализует более тысячи этих классов Qt в наборе модулей Python, все из которых содержатся в пакете Python верхнего уровня под названием PyQt5 .

PyQt5 совместим с Windows, Unix, Linux, macOS, iOS и Android. Это может быть привлекательной функцией, если вы ищете библиотеку или фреймворк для разработки многоплатформенных приложений с естественным внешним видом на каждой платформе.

PyQt5 доступен под двумя лицензиями:

  1. Коммерческая лицензия на берегу реки
  2. Стандартная общественная лицензия (GPL), версия 3

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

Примечание: Компания Qt разработала и в настоящее время поддерживает собственную привязку Python для библиотеки Qt. Библиотека Python называется Qt для Python и считается официальной Qt для Python. В этом случае пакет Python называется PySide2.

Поскольку PyQt5 и PySide2 построены поверх Qt, их API-интерфейсы очень похожи, даже почти идентичны.Вот почему перенос кода PyQt5 на PySide2 может быть таким же простым, как обновление некоторых операций импорта. Если вы выучите один из них, вы сможете работать с другим с минимальными усилиями. Если вы хотите глубже погрузиться в различия между этими двумя библиотеками, вы можете ознакомиться со следующими ресурсами:

Установка PyQt

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

Другой вариант - использовать двоичные колеса. Колеса - очень популярный способ управлять установкой пакетов Python. Однако вы должны учитывать, что колеса для PyQt5 доступны только для Python 3.5 и новее. Есть колеса на:

  • Linux (64-разрядная)
  • macOS
  • Windows (32- и 64-разрядная версии)

Все эти колеса включают копии соответствующих библиотек Qt, поэтому вам не нужно устанавливать их отдельно.

Третий вариант - использовать менеджеры пакетов в дистрибутивах Linux и macOS. Для Windows вы можете использовать двоичный файл .exe . Четвертый и последний вариант - использовать дистрибутив Anaconda для установки PyQt в вашей системе. В следующих нескольких разделах вы познакомитесь с некоторыми вариантами правильной установки PyQt5 из разных источников и на разных платформах.

Общесистемная установка с трубкой

Если вы используете Python 3.5 или более поздней версии, вы можете установить PyQt5 из PyPI, выполнив следующую команду:

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

Установка виртуальной среды с

pip

Вы можете решить не устанавливать PyQt непосредственно в вашей базовой системе, чтобы не испортить вашу конфигурацию.В этом случае вы можете использовать виртуальную среду Python. Используйте следующие команды, чтобы создать его и установить PyQt5:

  $ python3 -m venv pyqtvenv
$ source pyqtvenv / bin / активировать
(pyqtvenv) $ pip установить pyqt5
Сбор pyqt5
...
Успешно установлен PyQt5-sip-4.19.17 pyqt5-5.12.2
  

Здесь вы создаете виртуальную среду с venv . После его активации вы устанавливаете pyqt5 в этой среде с pip install pyqt5 . Этот вариант установки является наиболее рекомендуемым вариантом, если вы хотите, чтобы ваша базовая система оставалась чистой.

Установка для конкретной платформы

В экосистеме Linux несколько дистрибутивов включают бинарные пакеты для PyQt в свои репозитории. Если это верно для вашего дистрибутива, вы можете установить библиотеку с помощью диспетчера пакетов дистрибутива. Например, в Ubuntu 18.04 вы можете использовать следующую команду:

  $ sudo apt install python3-pyqt5
  

С помощью этой команды вы установите PyQt5 и все его зависимости в свою базовую систему, чтобы вы могли использовать библиотеку в любом из ваших проектов графического интерфейса.Обратите внимание, что необходимы привилегии root, которые вы вызываете здесь с помощью sudo .

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

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

Примечание: Если вы используете диспетчер пакетов в Linux или macOS, есть вероятность, что у вас не будет последней версии PyQt5.Установка pip будет лучше, если вы хотите, чтобы у вас была последняя версия.

Если вы предпочитаете использовать Windows, но решили не использовать двоичные колеса, то ваш путь через установку PyQt может быть болезненным. Это связано с тем, что страница загрузки PyQt5, похоже, больше не предоставляет двоичные файлы Windows (файлы .exe, ) для более поздних версий. Тем не менее, вы можете найти некоторые бинарные пакеты Windows для более старых версий библиотеки на странице проекта. Последний двоичный файл был создан для PyQt v5.6.

Если вам действительно нужно установить PyQt таким образом, вам потребуется:

  1. Определите, какую версию Python вы используете, и какой у вас Python - 32-разрядный или 64-разрядный.
  2. Загрузите правильную версию для вашей установки Python
  3. Установите PyQt, запустив файл .exe и следуя инструкциям на экране

Установка Anaconda

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

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

  • pyqt : привязка Python для кроссплатформенного инструментария GUI Qt (коммерческая, GPL-2.0, лицензии GPL-3.0)
  • anyqt : уровень совместимости для PyQt4 / PyQt5 (лицензия GPL-3.0)
  • qtpy : слой абстракции PyQt5 / PyQt4 / PySide (лицензия MIT)
  • pyqtgraph : Библиотека Python для научной графики (лицензия MIT)

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

Примечание: Обратите внимание, что установка Anaconda займет большой объем дискового пространства.Если вы установите Anaconda только для использования пакетов PyQt, тогда в вашей системе будет большое количество неиспользуемых пакетов и библиотек. Помните об этом, когда думаете об использовании дистрибутива Anaconda.

Создание вашего первого приложения PyQt

Теперь, когда у вас есть работающая установка PyQt, вы готовы приступить к написанию кода. Вы собираетесь создать «Hello, World!» приложение с Python и PyQt. Вот шаги, которые вы должны выполнить:

  1. Импортируйте QApplication и все необходимые виджеты из PyQt5.QtWidgets .
  2. Создайте экземпляр QApplication .
  3. Создайте экземпляр графического интерфейса вашего приложения.
  4. Показать графический интерфейс вашего приложения.
  5. Запустите цикл обработки событий вашего приложения (или основной цикл).

Вы можете загрузить исходный код примеров, которые вы рассмотрите в этом разделе, по ссылке ниже:

Вы начнете с файла с именем hello.py в вашем текущем рабочем каталоге:

  # Имя файла: hello.ру

"" "Простой пример Hello World с PyQt5." ""

import sys

# 1. Импортируйте `QApplication` и все необходимые виджеты.
из PyQt5.QtWidgets импортировать QApplication
из PyQt5.QtWidgets импортировать QLabel
из PyQt5.QtWidgets импортировать QWidget
  

Сначала вы импортируете sys , что позволит вам обрабатывать статус выхода приложения. Затем вы импортируете QApplication , QWidget и QLabel из QtWidgets , который является частью пакета под названием PyQt5 .Вы будете использовать этот импорт позже, но пока вы закончили с первым шагом.

Для второго шага необходимо создать экземпляр QApplication следующим образом:

  # 2. Создайте экземпляр QApplication
app = QApplication (sys.argv)
  

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

Примечание: sys.argv содержит список аргументов командной строки, переданных в сценарий Python. Если ваше приложение не будет принимать аргументы командной строки, вы можете использовать пустой список вместо sys.argv . То есть вы можете сделать что-то вроде app = QApplication ([]) .

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

  # 3. Создайте экземпляр графического интерфейса вашего приложения.
окно = QWidget ()
window.setWindowTitle ('Приложение PyQt5')
window.setGeometry (100, 100, 280, 80)
window.move (60, 15)
helloMsg = QLabel ('

Hello World!

', parent = window) helloMsg.move (60, 15)

В этом коде window является экземпляром QWidget , который предоставляет все функции, необходимые для создания окна (или формы) приложения.С помощью .setWindowTitle () вы можете добавить заголовок в окно вашего приложения. В этом случае отображается заголовок PyQt5 App .

Вы можете использовать .setGeometry () , чтобы определить размер окна и место его размещения на экране. Первые два параметра - это координаты x и y , в которых окно будет размещено на экране. Третий и четвертый параметры - это ширина и высота окна.

Каждому функциональному приложению с графическим интерфейсом нужны виджеты! Здесь вы используете объект QLabel ( helloMsg ), чтобы показать сообщение Hello World! в окне вашего приложения. Объекты QLabel могут принимать текст HTML, поэтому вы можете использовать элемент HTML '

Hello World!

' для форматирования текста как заголовка h2 . Наконец, вы используете .move () , чтобы разместить helloMsg с координатами (60, 15) в окне вашего приложения.

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

Отношения родитель-потомок используются для двух взаимодополняющих целей:

  1. Виджет, у которого нет родительского элемента , - это главное окно или окно верхнего уровня .
  2. Виджет, имеющий родительский элемент (который всегда является другим виджетом), содержится (или отображается) в своем родительском элементе .

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

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

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

  # 4. Показать графический интерфейс вашего приложения
window.show ()

# 5. Запустите цикл обработки событий вашего приложения (или основной цикл).
sys.exit (app.exec_ ())
  

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

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

Наконец, вы запускаете цикл обработки событий приложения, вызывая app.exec_ () . Вызов .exec_ () заключен в вызов sys.exit () , что позволяет вам полностью выйти из Python и освободить ресурсы памяти при завершении работы приложения. Вы можете запустить hello.py с помощью следующей команды:

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

Здесь ваше приложение показывает окно (на основе QWidget ) с сообщением Hello World! на нем.Чтобы показать сообщение, вы используете QLabel , который содержит сообщение в формате HTML.

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

С учетом стилей кода

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

В отношении этой проблемы в PEP 8 говорится, что:

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

Кроме того, Дзен Питона говорит:

… практичность важнее чистоты. (Источник)

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

Изучение основ PyQt

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

  • Виджеты
  • Менеджеры по расположению
  • Диалоги
  • Основные окна
  • Приложения
  • Циклы событий
  • Сигналы и слоты

Эти элементы будут строительными блоками ваших приложений PyQt GUI.Большинство из них представлены в виде классов Python. PyQt5.QtWidgets - это модуль, который предоставляет все эти классы. Эти элементы чрезвычайно важны, поэтому вы рассмотрим их в следующих нескольких разделах.

Виджеты

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

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

  • Кнопки
  • Этикетки
  • Линия правок
  • Комбинированные блоки
  • Радиокнопки

Давайте подробнее рассмотрим каждый из этих виджетов.Первой идет кнопка . Вы можете создать кнопку, создав экземпляр QPushButton , класса, который предоставляет классическую командную кнопку. Типичные кнопки: ОК , Отмена , Применить , Да , Нет и Закрыть . Вот как они выглядят в системе Linux:

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

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

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

Еще одним распространенным виджетом является строка редактирования , однострочное текстовое поле, которое можно создать с помощью QLineEdit .Редактирование строк полезно, когда вам нужно, чтобы пользователь вводил или редактировал данные в текстовом формате. Вот как они выглядят в системе Linux:

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

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

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

Последний виджет, о котором вы здесь расскажете, - это радиокнопка , которую вы можете создать с помощью QRadioButton .Объект QRadioButton - это кнопка выбора, которая может быть включена (отмечена) или выключена (не отмечена). Радиокнопки полезны, когда вам нужно, чтобы пользователь выбрал один из множества вариантов. В этом случае все параметры отображаются на экране одновременно:

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

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

Менеджеры по макету

Теперь вы знаете, что такое виджеты и как их использовать для создания графических интерфейсов. Но как организовать набор виджетов для создания последовательного и функционального графического интерфейса? Существует множество методов, которые можно использовать для размещения виджетов в форме или окне.Например, вы можете использовать .resize () и .move () , чтобы задать абсолютные размеры и положения виджетов. Однако у этого могут быть некоторые недостатки:

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

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

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

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

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

  1. QHBoxLayout
  2. QVBoxLayout
  3. QGridLayout
  4. QFormLayout

Первый класс менеджера компоновки - это QHBoxLayout , который упорядочивает виджеты по горизонтали слева направо:

Виджеты появятся один рядом с другим, начиная слева.

В этом примере кода показано, как использовать QHBoxLayout для размещения кнопок по горизонтали:

  1 # Имя файла: h_layout.ру
 2
 3 "" "Пример горизонтальной компоновки." ""
 4
 5import sys
 6
 7из PyQt5. QtWidgets импортировать QApplication
 8из PyQt5. QtWidgets импортируют QHBoxLayout
 9из PyQt5. QtWidgets импортировать QPushButton
10 из PyQt5. QtWidgets импортировать QWidget
11
12app = QApplication (sys.argv)
13window = QWidget ()
14window.setWindowTitle ('QHBoxLayout')
15layout = QHBoxLayout ()
16layout.addWidget (QPushButton ('Влево'))
17layout.addWidget (QPushButton ('Центр'))
18layout.addWidget (QPushButton ('Вправо'))
19window.setLayout (макет)
20окно.Показать()
21sys.exit (app.exec_ ())
  

Выделенные строки здесь творит чудеса:

  • Строка 15 создает объект QHBoxLayout с именем layout .
  • Строки с 16 по 18 добавляют три кнопки в макет с помощью .addWidget ()
  • Строка 19 устанавливает макет в качестве макета вашего окна с помощью .setLayout () .

При запуске python3 h_layout.py из командной строки, вы получите следующий результат:

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

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

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

Вот как можно создать и использовать объект QVBoxLayout :

  1 # Имя файла: v_layout.py
 2
 3 "" "Пример вертикальной компоновки." ""
 4
 5import sys
 6
 7из PyQt5. QtWidgets импортировать QApplication
 8из PyQt5. QtWidgets импортировать QPushButton
 9из PyQt5. QtWidgets импортируют QVBoxLayout
10 из PyQt5. QtWidgets импортировать QWidget
11
12app = QApplication (sys.argv)
13window = QWidget ()
14window.setWindowTitle ('QVBoxLayout')
15layout = QVBoxLayout ()
16layout.addWidget (QPushButton ('Вверху'))
17layout.addWidget (QPushButton ('Центр'))
18layout.addWidget (QPushButton ('Снизу'))
19window.setLayout (макет)
20window.show ()
21sys.exit (app.exec_ ())
  

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

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

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

Третий класс менеджера компоновки - QGridLayout , который упорядочивает виджеты в сетку из строк и столбцов. Каждый виджет будет иметь относительное положение в сетке. Вы можете определить положение виджета, передав ему пару координат в виде (строка, столбец) . Эти координаты должны быть действительными int числа. Они определяют, в какую ячейку сетки вы собираетесь поместить виджет.Схема сетки работает следующим образом:

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

Вот как использовать QGridLayout в вашем графическом интерфейсе:

  1 # Имя файла: g_layout.py
 2
 3 "" "Пример компоновки сетки." ""
 4
 5import sys
 6
 7из PyQt5. QtWidgets импортировать QApplication
 8из PyQt5. QtWidgets импортируют QGridLayout
 9 из PyQt5.QtWidgets импортировать QPushButton
10 из PyQt5. QtWidgets импортировать QWidget
11
12app = QApplication (sys.argv)
13window = QWidget ()
14window.setWindowTitle ('QGridLayout')
15layout = QGridLayout ()
16layout.addWidget (QPushButton ('Кнопка (0, 0)'), 0, 0)
17layout.addWidget (QPushButton ('Кнопка (0, 1)'), 0, 1)
18layout.addWidget (QPushButton ('Кнопка (0, 2)'), 0, 2)
19layout.addWidget (QPushButton ('Кнопка (1, 0)'), 1, 0)
20layout.addWidget (QPushButton ('Кнопка (1, 1)'), 1, 1)
21layout.addWidget (QPushButton ('Кнопка (1, 2)'), 1, 2)
22layout.addWidget (QPushButton ('Кнопка (2, 0)'), 2, 0)
23layout.addWidget (QPushButton ('Button (2, 1) + 2 Columns Span'), 2, 1, 1, 2)
24window.setLayout (макет)
25window.show ()
26sys.exit (app.exec_ ())
  

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

В строке 23 вы добавляете еще два аргумента к .addWidget () . Эти аргументы называются rowSpan и columnSpan , и они являются четвертым и пятым аргументами, передаваемыми функции. Вы можете использовать их, чтобы виджет занимал более одной строки или столбца, как в случае с QPushButton ('Button (2, 1) + 2 Columns Span') здесь.

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

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

Последний класс менеджера компоновки - QFormLayout , который упорядочивает виджеты в виде двух столбцов. В первом столбце сообщения обычно отображаются в виде ярлыков. Второй столбец обычно содержит такие виджеты, как QLineEdit , QComboBox , QSpinBox и т. Д. Они позволяют пользователю вводить или редактировать данные, относящиеся к информации в первом столбце. На следующей диаграмме показано, как макеты форм работают на практике:

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

В следующем примере показано, как создать приложение, использующее объект QFormLayout для упорядочивания своих виджетов:

  1 # Имя файла: f_layout.py
 2
 3 "" "Пример макета формы." ""
 4
 5import sys
 6
 7из PyQt5. QtWidgets импортировать QApplication
 8из PyQt5. QtWidgets импортируют QFormLayout
 9 из PyQt5.QtWidgets импортировать QLineEdit
10 из PyQt5. QtWidgets импортировать QWidget
11
12app = QApplication (sys.argv)
13window = QWidget ()
14window.setWindowTitle ('QFormLayout')
15layout = QFormLayout ()
16layout.addRow ('Имя:', QLineEdit ())
17layout.addRow ('Возраст:', QLineEdit ())
18layout.addRow ('Задание:', QLineEdit ())
19layout.addRow ('Хобби:', QLineEdit ())
20window.setLayout (макет)
21window.show ()
22sys.exit (приложение.exec_ ())
  

Строки с 15 по 20 выполняют тяжелую работу в этом примере. Обратите внимание, что QFormLayout имеет удобный метод под названием .addRow () . Вы можете использовать этот метод, чтобы добавить в макет строку с двумя виджетами. Первый аргумент .addRow () должен быть меткой, а второй аргумент должен быть любым другим виджетом, который позволяет пользователю вводить или редактировать данные.

Если вы запустите этот код, вы получите следующий результат:

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

Диалоги

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

  1. Приложение в стиле главного окна: Главное окно приложения является наследником QMainWindow .
  2. Приложение в стиле диалога: Главное окно приложения является наследником QDialog .

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

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

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

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

  • Модальные диалоговые окна: блокировать ввод в любые другие видимые окна в том же приложении. Вы можете отобразить модальное диалоговое окно, вызвав .exec_ () .
  • Немодальные диалоги: работают независимо от других окон в том же приложении. Вы можете отобразить немодальное диалоговое окно, используя .show () .

Диалоговые окна также могут предоставлять возвращаемое значение и иметь кнопки по умолчанию (например, OK и Отмена ).

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

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

  1 # Имя файла: диалог.ру
 2
 3 "" "Приложение в стиле диалога." ""
 4
 5import sys
 6
 7из PyQt5. QtWidgets импортировать QApplication
 8из PyQt5. QtWidgets импортировать QDialog
 9из PyQt5. QtWidgets импортировать QDialogButtonBox
10 из PyQt5. QtWidgets импортируют QFormLayout
11 из PyQt5. QtWidgets импортировать QLineEdit
12 из PyQt5. QtWidgets импортируют QVBoxLayout
13
Диалог 14 классов (QDialog):
15 "" "Диалог." ""
16 def __init __ (self, parent = None):
17 "" "Инициализатор." ""
18 super () .__ init __ (родитель)
19 self.setWindowTitle ('QDialog')
20 dlgLayout = QVBoxLayout ()
21 formLayout = QFormLayout ()
22 formLayout.addRow ('Имя:', QLineEdit ())
23 formLayout.addRow ('Возраст:', QLineEdit ())
24 formLayout.addRow ('Задание:', QLineEdit ())
25 formLayout.addRow ('Хобби:', QLineEdit ())
26 dlgLayout.addLayout (formLayout)
27 btns = QDialogButtonBox ()
28 btns.setStandardButtons (
29 QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
30 dlgLayout.addWidget (btns)
31 self.setLayout (dlgLayout)
32
33 если __name__ == '__main__':
34 приложение = QApplication (sys.argv)
35 dlg = Диалог ()
36 дл.Показать()
37 системный выход (app.exec_ ())
  

Это приложение немного сложнее. Вот что происходит:

  • Строка 14 создает полный класс Dialog для графического интерфейса пользователя, который наследуется от QDialog .
  • Строка 20 назначает объект QVBoxLayout dlgLaout .
  • Строка 21 назначает объект QVFormLayout для formLayout .
  • Строки с 22 по 25 добавить виджеты в форму formLayout .
  • Строка 26 использует dlgLayout для размещения всех виджетов в форме.
  • Строка 27 предоставляет удобный объект для размещения диалоговых кнопок.
  • Строки 28 и 29 добавляют две стандартные кнопки: Ok и Cancel .
  • Строки с 33 по 37 заключают шаблонный код в if __name__ == '__main__': идиома. Это считается лучшей практикой для питонистов.

Примечание: Если вы посмотрите на строку 26 в блоке кода выше, то заметите, что менеджеры компоновки могут быть вложены друг в друга.Вы можете вложить макеты, вызвав .addLayout () в макете контейнера и передав вложенный макет в качестве аргумента этому методу.

Приведенный выше блок кода отображает следующее окно:

Это графический интерфейс, который вы создали с помощью QFormLayout для виджетов и QVBoxLayout для общего макета приложения ( dlgLayout в строке 20).

Основные окна

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

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

  • Одна строка меню находится в верхней части окна. Строка меню содержит главное меню приложения.

  • Несколько панелей инструментов находятся по бокам окна. Панели инструментов подходят для размещения кнопок инструментов и других видов виджетов, таких как QComboBox , QSpinBox и других.

  • Один центральный виджет находится в центре окна. Центральный виджет может быть любого типа или составным.

  • Несколько виджетов док-станции находятся вокруг центрального виджета. Виджеты док-станции - это маленькие подвижные окна.

  • Одна строка состояния находится внизу окна. В строке состояния отображается информация об общем состоянии приложения.

Невозможно создать главное окно без предварительной настройки центрального виджета.У вас должен быть центральный виджет, даже если это просто заполнитель. В этом случае вы можете использовать объект QWidget в качестве центрального виджета. Вы можете установить центральный виджет главного окна с помощью .setCentralWidget () . Компоновка главного окна позволит вам иметь только один центральный виджет, но это может быть один или составной виджет.

В следующем примере кода показано, как использовать QMainWindow для создания приложения в стиле главного окна:

  1 # Имя файла: main_window.ру
 2
 3 "" "Приложение в стиле главного окна." ""
 4
 5import sys
 6
 7из PyQt5. QtWidgets импортировать QApplication
 8из PyQt5. QtWidgets импортировать QLabel
 9из PyQt5. QtWidgets импортировать QMainWindow
10 из PyQt5. QtWidgets импортировать QStatusBar
11 из PyQt5. QtWidgets импортировать QToolBar
12
Окно класса 13 (QMainWindow):
14 "" "Главное окно." ""
15 def __init __ (self, parent = None):
16 "" "Инициализатор." ""
17 super () .__ init __ (родитель)
18 self.setWindowTitle ('QMainWindow')
19 self.setCentralWidget (QLabel («Я центральный виджет»))
20 сам._createMenu ()
21 self._createToolBar ()
22 self._createStatusBar ()
23
24 def _createMenu (сам):
25 self.menu = self.menuBar (). AddMenu ("& Меню")
26 self.menu.addAction ('& Exit', self.close)
27
28 def _createToolBar (сам):
29 инструментов = QToolBar ()
30 self.addToolBar (инструменты)
31 tools.addAction ('Выход', self.close)
32
33 def _createStatusBar (сам):
34 статус = QStatusBar ()
35 status.showMessage («Я - строка состояния»)
36 сам.setStatusBar (статус)
37
38 если __name__ == '__main__':
39 приложение = QApplication (sys.argv)
40 побед = Окно ()
41 win.show ()
42 sys.exit (app.exec_ ())
  

Вот как работает этот код:

  • Строка 13 создает класс Window , который наследуется от QMainWindow .
  • Строка 18 устанавливает заголовок окна.
  • Строка 19 устанавливает QLabel в качестве центрального виджета.
  • Строки с 20 по 22 вызывают частные методы в следующих строках для создания различных элементов графического интерфейса:
    • Строки с 24 по 26 создают главное меню.
    • Строки с 28 по 31 создают панель инструментов.
    • Строки с 33 по 36 создают строку состояния.

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

Когда вы запустите приведенный выше код, вы увидите следующее окно:

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

  • Одно главное меню под названием Меню
  • Одна панель инструментов с функциональной Кнопка выхода
  • Один центральный виджет (объект QLabel )
  • Одна строка состояния внизу окна

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

Приложения

Самый простой класс, который вы будете использовать при разработке приложений PyQt GUI, - это QApplication . Этот класс лежит в основе любого приложения PyQt. Он управляет потоком управления приложением, а также его основными настройками. В PyQt любой экземпляр QApplication считается приложением . Каждое приложение PyQt GUI должно иметь один объект QApplication .Некоторые из обязанностей приложения включают:

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

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

Одной из наиболее важных задач QApplication является обеспечение цикла событий и всего механизма обработки событий. Давайте теперь подробнее рассмотрим цикл обработки событий.

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

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

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

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

В PyQt вы можете запустить цикл обработки событий приложения, вызвав .exec_ () для объекта QApplication .

Примечание. PyQt был впервые разработан для Python 2, в котором уже есть ключевое слово exec .В более ранних версиях в конец .exec_ () добавлялось подчеркивание, чтобы избежать конфликтов имен.

PyQt5 нацелен на Python 3, в котором нет ключевого слова exec . Тем не менее, библиотека предоставляет два метода, запускающих цикл обработки событий:

  1. .exec_ ()
  2. .exec ()

Это означает, что вы можете удалить .exec_ () из своего кода, а вместо этого можете безопасно использовать .exec () .

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

Сигналы и слоты

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

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

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

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

Для подключения сигнала к слоту можно использовать следующий синтаксис:

  widget.signal.connect (slot_function)
  

Это подключит slot_function к widget.signal . Каждый раз, когда испускается сигнал , будет вызываться slot_function () .

Этот код показывает вам, как использовать механизм сигналов и слотов:

  1 # Имя файла: signal_slots.ру
 2
 3 "" "Пример сигналов и слотов." ""
 4
 5import sys
 6
 7из PyQt5. QtWidgets импортировать QApplication
 8из PyQt5. QtWidgets импортировать QLabel
 9из PyQt5. QtWidgets импортировать QPushButton
10 из PyQt5. QtWidgets импортируют QVBoxLayout
11 из PyQt5. QtWidgets импортировать QWidget
12
13def приветствие ():
14 "" "Функция слота." ""
15, если msg.text ():
16 msg.setText ("")
Еще 17:
18 msg.setText («Привет, мир!»)
19
20app = QApplication (sys.argv)
21window = QWidget ()
22window.setWindowTitle ('Сигналы и слоты')
23layout = QVBoxLayout ()
24
25btn = QPushButton ('Приветствовать')
26btn.clicked.connect (приветствие) # Подключиться к приветствию ()
27
28layout.addWidget (btn)
29msg = QLabel ('')
30layout.addWidget (сообщение)
31window.setLayout (макет)
32window.show ()
33sys.exit (приложение.exec_ ())
  

В строке 13 вы создаете приветствие () , которое вы будете использовать в качестве слота. Затем в строке 26 вы соединяете сигнал кнопки clicked с приветствием () . Таким образом, всякий раз, когда пользователь нажимает кнопку, вызывается welcome () , и msg будет чередоваться между сообщением Hello World! и пустая строка:

Когда вы нажимаете Greet , появляется Hello World! Сообщение появится и исчезнет на вашем экране.

Примечание: Каждый виджет имеет собственный набор предопределенных сигналов. Вы можете проверить их на странице документации виджета.

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

  def приветствие (кто):
    "" "Функция слота." ""
    если msg.text ():
        msg.setText ('')
    еще:
        msg.setText (ф'Привет {кто} ')
  

Теперь, welcome () должен получить аргумент с именем who .Если вы хотите связать эту новую версию welcome () с сигналом btn.clicked , вы можете сделать что-то вроде этого:

  btn.clicked.connect (functools.partial (приветствие, «Мир!»))
  

Чтобы этот код работал, вам нужно сначала импортировать functools . Вызов функции functools.partial () возвращает объект, который ведет себя аналогично вызову welcome () с who = 'World!' . Теперь, когда пользователь нажимает кнопку, появляется сообщение «Hello World!». будет отображаться на этикетке так же, как и раньше.

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

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

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

Давай!

Создание калькулятора с Python и PyQt

В этом разделе вы собираетесь разработать калькулятор, используя шаблон проектирования модель-представление-контроллер (MVC). Этот шаблон имеет три уровня кода, каждый с разными ролями:

  1. Модель заботится о бизнес-логике вашего приложения.Он содержит основные функции и данные. Для вашего калькулятора модель выполнит вычисления.

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

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

Вот пошаговый шаблон MVC для настольного приложения с графическим интерфейсом пользователя:

  1. Пользователь выполняет действие или запрос (событие) в представлении (GUI).
  2. Представление уведомляет контроллер о действии пользователя.
  3. Контроллер получает запрос пользователя и запрашивает у модели ответ.
  4. Модель обрабатывает запрос контроллера, выполняет необходимые операции и возвращает ответ или результат.
  5. Контроллер получает ответ модели и соответствующим образом обновляет представление.
  6. Пользователь наконец видит запрошенный результат в представлении.

Вы будете использовать этот шаблон проектирования MVC для создания калькулятора.

Создание скелета

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

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

  #! / Usr / bin / env python3

# Имя файла: pycalc.ру

"" "PyCalc - это простой калькулятор, построенный с использованием Python и PyQt5." ""

import sys

# Импортировать QApplication и необходимые виджеты из PyQt5.QtWidgets
из PyQt5.QtWidgets импортировать QApplication
из PyQt5.QtWidgets импортировать QMainWindow
из PyQt5.QtWidgets импортировать QWidget

__version__ = '0,1'
__author__ = 'Леоданис Посо Рамос'

# Создайте подкласс QMainWindow для настройки графического интерфейса калькулятора
класс PyCalcUi (QMainWindow):
    "" "Просмотр PyCalc (GUI)." ""
    def __init __ (сам):
        "" "Просмотр инициализатора."" "
        супер () .__ init __ ()
        # Установить некоторые свойства главного окна
        self.setWindowTitle ('PyCalc')
        self.setFixedSize (235, 235)
        # Установить центральный виджет
        self._centralWidget = QWidget (сам)
        self.setCentralWidget (self._centralWidget)

# Клиентский код
def main ():
    """Основная функция."""
    # Создать экземпляр QApplication
    pycalc = QApplication (sys.argv)
    # Показать графический интерфейс калькулятора
    view = PyCalcUi ()
    view.show ()
    # Выполнить основной цикл калькулятора
    sys.выход (pycalc.exec_ ())

если __name__ == '__main__':
    главный()
  

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

  • Строки с 10 по 12 импортируют необходимые модули и классы из PyQt5.QtWidgets .

  • Строка 18 создает графический интерфейс с классом PyCalcUi . Обратите внимание, что этот класс наследуется от QMainWindow .

  • Строка 24 устанавливает заголовок окна на PyCalc .

  • Строка 25 использует .setFixedSize () , чтобы дать окну фиксированный размер. Это гарантирует, что пользователь не сможет изменить размер окна.

  • Строка 27 создает объект QWidget , который играет роль центрального виджета. Помните, что, поскольку ваш класс GUI наследуется от QMainWindow , вам нужен центральный виджет.Этот объект будет родительским для остальной части компонента графического интерфейса.

  • Строка 31 определяет основную функцию вашего калькулятора, что считается передовой практикой. Эта функция будет точкой входа в приложение. Внутри main () ваша программа выполняет следующие действия:

    • Строка 34 создает объект QApplication pycalc .
    • Строка 37 показывает графический интерфейс с представлением .показать () .
    • Строка 39 запускает цикл обработки событий приложения с pycalc.exec_ () .

Когда вы запустите скрипт, на вашем экране появится следующее окно:

Это скелет вашего графического интерфейса пользователя.

Завершение обзора

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

Сначала вам нужно добавить следующий импорт в начало файла:

  из PyQt5.QtCore import Qt
из PyQt5.QtWidgets импортировать QGridLayout
из PyQt5.QtWidgets импортировать QLineEdit
из PyQt5.QtWidgets импортировать QPushButton
из PyQt5.QtWidgets импортировать QVBoxLayout
  

Вы собираетесь использовать QVBoxLayout для общей компоновки калькулятора. Вы также будете использовать объект QGridLayout для расположения кнопок. Наконец, вы импортируете QLineEdit для дисплея и QPushButton для кнопок.Теперь в верхней части файла должно быть восемь операторов импорта.

Теперь вы можете обновить инициализатор для PyCalcUi :

  # Создайте подкласс QMainWindow для настройки графического интерфейса калькулятора
класс PyCalcUi (QMainWindow):
    "" "Просмотр PyCalc (GUI)." ""
    def __init __ (сам):
        "" "Просмотр инициализатора." ""
        супер () .__ init __ ()
        # Установить некоторые свойства главного окна
        self.setWindowTitle ('PyCalc')
        self.setFixedSize (235, 235)
        # Установите центральный виджет и общий макет
        себя.generalLayout = QVBoxLayout ()
        self._centralWidget = QWidget (сам)
        self.setCentralWidget (self._centralWidget)
        self._centralWidget.setLayout (self.generalLayout)
        # Создаем дисплей и кнопки
        self._createDisplay ()
        self._createButtons ()
  

Здесь вы добавили выделенные строки кода. Вы будете использовать QVBoxLayout , чтобы разместить дисплей вверху, а кнопки в виде сетки внизу.

Звонки на ._createDisplay () и ._createButtons () не будут работать, потому что вы еще не реализовали эти методы. Давайте исправим это, написав ._createDisplay () :

.
  класс PyCalcUi (QMainWindow):
    # Snip
    def _createDisplay (сам):
        "" "Создать дисплей." ""
        # Создаем виджет отображения
        self.display = QLineEdit ()
        # Установить некоторые свойства дисплея
        self.display.setFixedHeight (35)
        self.display.setAlignment (Qt.AlignRight)
        себя.display.setReadOnly (Истина)
        # Добавить отображение в общий макет
        self.generalLayout.addWidget (self.display)
  

Для создания виджета отображения используется объект QLineEdit . Затем вы устанавливаете следующие свойства отображения:

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

Последняя строка добавляет дисплей к общему макету калькулятора с generalLayout.addWidget () .

Затем вы реализуете ._createButtons () для создания кнопок для вашего калькулятора. Вы будете использовать словарь, чтобы удерживать текст каждой кнопки и ее положение в сетке. Вы также будете использовать QGridLayout , чтобы расположить кнопки в окне калькулятора. Окончательный код будет выглядеть так:

  класс PyCalcUi (QMainWindow):
    # Snip
    def _createButtons (сам):
        "" "Создайте кнопки." ""
        self.buttons = {}
        buttonsLayout = QGridLayout ()
        # Текст кнопки | позиция в QGridLayout
        кнопки = {'7': (0, 0),
                   '8': (0, 1),
                   '9': (0, 2),
                   '/': (0, 3),
                   'C': (0, 4),
                   '4': (1, 0),
                   '5': (1, 1),
                   '6': (1, 2),
                   '*': (1, 3),
                   '(': (1, 4),
                   '1': (2, 0),
                   '2': (2, 1),
                   '3': (2, 2),
                   '-': (2, 3),
                   ')': (2, 4),
                   '0': (3, 0),
                   '00': (3, 1),
                   '.': (3, 2),
                   '+': (3, 3),
                   '=': (3, 4),
                  }
        # Создайте кнопки и добавьте их в макет сетки
        для btnText, pos в buttons.items ():
            self.buttons [btnText] = QPushButton (btnText)
            self.buttons [btnText] .setFixedSize (40, 40)
            buttonsLayout.addWidget (self.buttons [btnText], pos [0], pos [1])
        # Добавить buttonLayout в общий макет
        self.generalLayout.addLayout (buttonsLayout)
  

Сначала вы создаете пустой словарь self.кнопки , чтобы удерживать кнопки калькулятора. Затем вы создаете временный словарь для хранения их меток и относительных позиций в макете сетки ( buttonsLayout ). Внутри цикла for вы создаете кнопки и добавляете их к self.buttons и buttonsLayout . Каждая кнопка будет иметь фиксированный размер 40x40 пикселей, который вы устанавливаете с помощью .setFixedSize (40, 40) .

Примечание: Что касается размера виджета, вы редко найдете единицы измерения в документации PyQt.Предполагается, что единица измерения составляет пикселей (за исключением QPrinter , который использует точек ).

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

  1. .setDisplayText () для установки и обновления текста на дисплее
  2. .displayText () для получения текста текущего дисплея
  3. .clearDisplay () для очистки текста на дисплее

Эти методы сформируют открытый интерфейс графического интерфейса пользователя и завершат класс представления для вашего калькулятора Python. Вот возможная реализация:

  класс PyCalcUi (QMainWindow):
    # Snip
    def setDisplayText (сам, текст):
        "" "Установить отображаемый текст." ""
        self.display.setText (текст)
        self.display.setFocus ()

    def displayText (self):
        "" "Получить отображаемый текст." ""
        вернуть self.display.текст()

    def clearDisplay (сам):
        "" "Очистить дисплей." ""
        self.setDisplayText ('')
  

Вот что делает каждая функция:

  • .setDisplayText () использует .setText () для установки и обновления текста на дисплее и .setFocus () для установки фокуса курсора на дисплее.

  • .displayText () - это метод получения, который возвращает текущий текст дисплея.Когда пользователь щелкает знак равенства ( = ), программа будет использовать возвращаемое значение .displayText () в качестве математического выражения для оценки.

  • .clearDisplay () устанавливает текст дисплея в пустую строку ( '' ), чтобы пользователь мог ввести новое математическое выражение.

Теперь графический интерфейс вашего калькулятора готов! Когда вы запустите приложение, вы увидите такое окно:

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

Создание базового контроллера

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

  из functools import partial
  

Вверху pycalc.py вы импортируете partial () для соединения сигналов с методами, которые должны принимать дополнительные аргументы.

Ваш класс контроллера должен выполнять три основные задачи:

  1. Доступ к общедоступному интерфейсу графического интерфейса
  2. Обработка создания математических выражений
  3. Кнопка подключения нажата сигнала с соответствующими слотами

Это обеспечит правильную работу вашего калькулятора.Вот как вы кодируете класс контроллера:

  # Создайте класс контроллера для подключения графического интерфейса и модели
класс PyCalcCtrl:
    "" "Класс контроллера PyCalc." ""
    def __init __ (я, просмотр):
        "" "Инициализатор контроллера." ""
        self._view = просмотр
        # Подключить сигналы и слоты
        self._connectSignals ()

    def _buildExpression (self, sub_exp):
        "" "Построить выражение." ""
        выражение = self._view.displayText () + sub_exp
        self._view.setDisplayText (выражение)

    def _connectSignals (сам):
        "" "Подключите сигналы и слоты."" "
        для btnText, btn в self._view.buttons.items ():
            если btnText отсутствует в {'=', 'C'}:
                btn.clicked.connect (частичное (self._buildExpression, btnText))

        self._view.buttons ['C']. clicked.connect (self._view.clearDisplay)
  

Первое, что вы делаете, это даете PyCalcCtrl экземпляр представления PyCalcUi . Вы будете использовать этот экземпляр, чтобы получить полный доступ к общедоступному интерфейсу представления. Затем вы создаете ._buildExpression () для обработки создания математических выражений.Этот метод также обновляет дисплей калькулятора в ответ на ввод данных пользователем.

Наконец, вы используете ._connectSignals () для соединения печатаемых кнопок с ._buildExpression () . Это позволяет вашим пользователям создавать математические выражения, нажимая кнопки калькулятора. В последней строке вы подключаете кнопку очистки ( C ) к ._view.clearDisplay () . Этот метод очистит текст на дисплее.

Для работы этого нового класса контроллера необходимо обновить main () :

  # Код клиента
def main ():
    """Основная функция."" "
    # Создать экземпляр QApplication
    pycalc = QApplication (sys.argv)
    # Показать графический интерфейс калькулятора
    view = PyCalcUi ()
    view.show ()
    # Создаем экземпляры модели и контроллера
    PyCalcCtrl (просмотр = просмотр)
    # Выполнить основной цикл калькулятора
    sys.exit (pycalc.exec_ ())
  

Этот код создает экземпляр PyCalcCtrl (view = view) с представлением , переданным в качестве аргумента. Это инициализирует контроллер и подключит сигналы и слоты, чтобы дать вашему калькулятору некоторую функциональность.

Если вы запустите приложение, вы увидите что-то вроде следующего:

Как видите, в калькуляторе уже есть полезные функции! Теперь вы можете строить математические выражения, нажимая на кнопки. Обратите внимание, что знак равенства ( = ) еще не работает. Чтобы исправить это, вам нужно реализовать модель калькулятора.

Реализация модели

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

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

У вашей модели будет одиночная функция:

  # Создать модель для обработки операции калькулятора
def AssessmentExpression (выражение):
    "" "Оцените выражение." ""
    пытаться:
        результат = str (eval (выражение, {}, {}))
    кроме исключения:
        результат = ERROR_MSG

    вернуть результат
  

Здесь вы используете eval () для оценки строки как выражения.В случае успеха вы вернете результат. В противном случае вы вернете сообщение об ошибке. Обратите внимание, что эта функция не идеальна. У него есть пара важных проблем:

  • Блок try ... except не перехватывает какое-либо конкретное исключение, что не является лучшей практикой в ​​Python.
  • Функция основана на использовании eval () , что может привести к серьезным проблемам с безопасностью. Общий совет - использовать eval () только для надежных входных данных.

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

Завершение работы с контроллером

После того, как вы закончили модель калькулятора, вы можете закончить контроллер. Окончательная версия PyCalcCtrl будет включать логику для обработки вычислений и проверки правильности работы знака равенства ( = ):

  # Создайте класс контроллера для подключения графического интерфейса и модели
класс PyCalcCtrl:
    "" "Контроллер PyCalc."" "
    def __init __ (я, модель, представление):
        "" "Инициализатор контроллера." ""
        self._evaluate = модель
        self._view = просмотр
        # Подключить сигналы и слоты
        self._connectSignals ()

    def _calculateResult (сам):
        "" "Оцените выражения." ""
        результат = self._evaluate (выражение = self._view.displayText ())
        self._view.setDisplayText (результат)

    def _buildExpression (self, sub_exp):
        "" "Построить выражение." ""
        если self._view.displayText () == ERROR_MSG:
            себя._view.clearDisplay ()

        выражение = self._view.displayText () + sub_exp
        self._view.setDisplayText (выражение)

    def _connectSignals (сам):
        "" "Подключите сигналы и слоты." ""
        для btnText, btn в self._view.buttons.items ():
            если btnText отсутствует в {'=', 'C'}:
                btn.clicked.connect (частичное (self._buildExpression, btnText))

        self._view.buttons ['=']. clicked.connect (self._calculateResult)
        self._view.display.returnPressed.connect (self._calculateResult)
        себя._view.buttons ['C']. clicked.connect (self._view.clearDisplay)
  

Выделены новые строки кода. Сначала вы добавляете новый параметр в функцию инициализации. Теперь класс получает экземпляры как от модели, так и от представления. Затем в ._calculateResult () вы берете содержимое дисплея, оцениваете его как математическое выражение и, наконец, показываете результат на дисплее.

Вы также добавляете оператор if к ._buildExpression () , чтобы проверить, произошла ли ошибка.Если да, то вы очищаете дисплей и начинаете заново с нового выражения. Наконец, вы добавляете еще два соединения внутри ._connectSignals () . Первый включает знак равенства ( = ). Второй гарантирует, что когда пользователь нажмет Enter , калькулятор обработает выражение, как ожидалось.

Чтобы весь этот код работал, нужно обновить main () :

  # Код клиента
def main ():
    """Основная функция."""
    # Создаем экземпляр `QApplication`
    pycalc = QApplication (sys.argv)
    # Показать графический интерфейс калькулятора
    view = PyCalcUi ()
    view.show ()
    # Создаем экземпляры модели и контроллера
    модель = оценкаВыражение
    PyCalcCtrl (модель = модель, представление = представление)
    # Выполнить основной цикл калькулятора
    sys.exit (pycalc.exec_ ())
  

Здесь ваша модель содержит ссылку на AssessmentExpression () . Кроме того, PyCalcCtrl () теперь получает два аргумента: модель и представление .

Запуск калькулятора

Теперь, когда вы закончили код, пришло время проверить! Если вы запустите приложение, то увидите что-то вроде этого:

Чтобы использовать PyCalc, введите с помощью мыши допустимое математическое выражение.Затем нажмите , введите или щелкните знак равенства ( = ), чтобы увидеть результат на дисплее калькулятора.

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

Заключение

Настольные приложения с графическим интерфейсом пользователя (GUI) по-прежнему занимают значительную долю рынка разработки программного обеспечения. Python предлагает несколько фреймворков и библиотек, которые могут помочь вам разрабатывать современные и надежные приложения с графическим интерфейсом.

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

Теперь вы можете:

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

Теперь вы можете использовать Python и PyQt, чтобы вдохнуть жизнь в свои настольные приложения с графическим интерфейсом пользователя! Вы можете получить исходный код проекта калькулятора и все примеры кода по ссылке ниже:

Дополнительная литература

Если вы хотите глубже погрузиться в PyQt и связанные с ним инструменты, вы можете взглянуть на некоторые из этих ресурсов:

Хотя документация PyQt5 является первым ресурсом, перечисленным здесь, некоторые важные части все еще отсутствуют или неполны.К счастью, вы можете использовать документацию PyQt4, чтобы заполнить пробелы. Справочник классов особенно полезен для получения полного понимания виджетов и классов.

Если вы используете документацию PyQt4 в качестве справочника для классов PyQt5, имейте в виду, что классы будут немного отличаться и также могут вести себя по-разному. Другой вариант - использовать вместо этого оригинальную документацию Qt v5 и ее справочник по классам. В этом случае вам может потребоваться некоторый опыт работы с C ++, чтобы правильно понять образцы кода.

.