Python + Pyside2 o simplemente "Calculadora"

Hola Habr!

Me llamo Sasha Soy un desarrollador junior. Yo trabajo como probador de software. Principalmente escribo pruebas usando Python + Selenium, ¡pero Python se volvió tan interesante que quería profundizar en ello y aprender tantos marcos como sea posible! Quería escribir una aplicación de escritorio, ala simple "Calculadora". Mi elección recayó en Pyside2. No pretendo tener el código o la lección perfectos. Simplemente existe el deseo de compartir experiencias si alguien, como yo, quiere comenzar a buscar en Python. Si ayudo a alguien, he logrado el resultado.

¡Empecemos!

Escribí mi código en PyBarm IDE de JetBrains. OS - Windows.

Instale PySide2:

pip install PySide2 

Donde tenga la carpeta raíz de Python, vaya a ella, luego a la carpeta “Lib” -> “site-packages” -> “Pyside2”. Tendrá el programa de diseñador: este es el programa QtDesigner, que le permitirá crear su propia interfaz para su programa. Vale la pena señalar que cuando cree su archivo en el directorio de su proyecto, tendrá el formato .ui , que Python no entenderá, por lo que tendremos que convertirlo al formato .py , pero esto es más tarde.

Primero, crea tu formulario.

imagen

Hacemos nuestro diseño, llame a los botones a la derecha en la subsección "Inspector de objetos". Vale la pena decir que QtDesigner admite una hoja de estilos en cascada, y si es más fácil, al encontrar el parámetro "styleSheet" en las propiedades, tiene la oportunidad de hacer su diseño basado en el conocimiento de CSS.

imagen

Luego, necesitamos convertir nuestro archivo .ui a un formato para que Python lo entienda. Ve a la línea de comando y escribe

 pyside2-uic "you_file.ui" -o "your_file.py" 

¿Qué hace el comando pyside2-uic? Convierte tu archivo .ui en un archivo pypy .py y crea una clase Python a partir de él. Quizás las personas con conocimientos dirán que un archivo ui puede conectarse sin conversión a un proyecto, pero estaré ordenado y lo haré mejor, como está escrito en los manuales de Pyside2.

Luego, ve al código.

Abra PyCharm, nuestro directorio de proyectos y cree un archivo llamado calc_ui.py o something_ui.py, dependiendo del programa que esté haciendo. El prefijo _ui al final del archivo nos ayudará a no perdernos en los archivos. En términos generales, debería verse así:

imagen

Comencemos editando el archivo que convertimos de .ui a .py .

A continuación buscamos este código y lo copiamos, luego lo eliminamos de este archivo.

 if __name__ == '__main__': import sys app = QtWidgets.QApplication(sys.argv) Form = QtGui.QWidget() ui = Ui_Form() ui.setupUi(Form) Form.show() sys.exit(app.exec_()) 

Creamos nuestro archivo principal, donde se escribirá la lógica del programa. Lo llamé, como no sorprendentemente, "calc.py" (arriba en la pantalla del directorio está visible).

Pegue nuestro código copiado allí y comience a editarlo.

importamos sistemas que lanzaremos al principio ya que es una regla de buena forma.

Importamos un par de módulos necesarios para trabajar con nuestro formulario y desde nuestro archivo "calc_ui.py" importamos la clase principal Ui_MainWindow .

A continuación, edite si __nombre__ . Eliminamos todo lo que no es necesario. Deberías tener esto:

 if __name__ == '__main__': #   QApplication app = QtWidgets.QApplication(sys.argv) #    ,     calc = Calculator() #  sys.exit(app.exec_()) 

Comenté sobre el código claramente con suerte. Pasemos a crear la clase Calculadora .

 class Calculator(QtWidgets.QMainWindow, Ui_MainWindow): #   def __init__(self): super().__init__() #    Ui ( ) self.setupUi(self) #    self.show() 

Además, nuestra tarea es asegurar que algo suceda cuando tocamos los botones "1", "2", "3", etc.

En el mismo lugar, en el constructor de la clase, declaramos la conexión del botón a cualquier función:

  # pressed self.pushButton.clicked.connect(self.digit_pressed) # 1 self.pushButton_2.clicked.connect(self.digit_pressed) # 2 self.pushButton_3.clicked.connect(self.digit_pressed) # 3 self.pushButton_4.clicked.connect(self.digit_pressed) # 4 self.pushButton_5.clicked.connect(self.digit_pressed) # 5 self.pushButton_6.clicked.connect(self.digit_pressed) # 6 self.pushButton_7.clicked.connect(self.digit_pressed) # 7 self.pushButton_8.clicked.connect(self.digit_pressed) # 8 self.pushButton_9.clicked.connect(self.digit_pressed) # 9 self.pushButton_10.clicked.connect(self.digit_pressed) # 0 self.pushButton_add.clicked.connect(self.pressed_equal) # + self.pushButton_ded.clicked.connect(self.pressed_equal) # - self.pushButton_div.clicked.connect(self.pressed_equal) # / self.pushButton_mul.clicked.connect(self.pressed_equal) # * self.pushButton_exp.clicked.connect(self.pressed_equal) # ** self.pushButton_log.clicked.connect(self.pressed_equal) # log self.pushButton_procent.clicked.connect(self.pressed_equal) # % self.pushButton_ENTER.clicked.connect(self.function_result) # = self.pushButton_C.clicked.connect(self.function_clear) # C self.pushButton_point.clicked.connect(self.make_fractional) # . self.pushButton_delete.clicked.connect(self.function_delete) # < self.pushButton_open_skob.clicked.connect(self.create_big_example) # ( 

La función self.digit_pressed ya está indicada en el código de los botones, echemos un vistazo, ¿qué hace si el usuario hace clic en el botón con números:

  # lineEdit -  ,         # text() -  ,      # setText() -          # sender() - ,     (   ,    ) def digit_pressed(self): button = self.sender() if self.lineEdit.text() == '0': #        "0",     ,     self.lineEdit.setText(button.text()) else: if self.result == self.lineEdit.text(): self.lineEdit.setText(button.text()) else: self.lineEdit.setText(self.lineEdit.text() + button.text()) self.result = 0 

Los comentarios sobre el código también están presentes.

Ahora considere una función que responderá a las operaciones de prensado "+" , "-" , etc.

  clear() -  ,       def pressed_equal(self): button = self.sender() self.first_value = float(self.lineEdit.text()) self.lineEdit.clear() self.label.setText(str(self.first_value) + button.text()) self.equal = button.text() 

Escribimos el primer valor en la variable self.first_value y borramos nuestro campo para ingresar el valor de la operación, y luego lo enviamos a lineEdit (nuestro campo principal de entrada y resultado) junto con el número y la operación.

¿Por qué flotar ? Puedo responder de modo que decidí hacer todo flotante , y al generar el valor en el bloque de resultados, si el resultado tiene ".0" al final, elimine esta parte para que el número sea un número entero. No pensé en uno mejor.

Ahora tenemos funciones para presionar números y para presionar operaciones, ¿qué sigue? A continuación, debemos mostrar el resultado, este es el botón = (ENTRAR) .

  def function_result(self): if self.equal == '+': self.function_addition() elif self.equal == '-': self.function_subtraction() elif self.equal == "/": self.function_divison() elif self.equal == '*': self.function_multiply() elif self.equal == "^": self.exponentiation() elif self.equal == "%": self.function_percent() elif self.equal == "log": self.function_log() 

Permítame recordarle que la variable self.first_value ahora es igual a la primera variable que presentamos, y self.equal contiene la operación en la que hicimos clic. Después de ingresar el segundo número y presionar = , tratamos de averiguar cuál es la operación y luego determinamos la segunda variable.

Pasamos a las funciones de las operaciones. Lo tengo así:

  def function_addition(self): self.determinate_second_value() self.result = float(self.first_value + self.second_value) self.form_result() def function_subtraction(self): self.determinate_second_value() self.result = float(self.first_value - self.second_value) self.form_result() def function_divison(self): self.determinate_second_value() self.result = float(self.first_value / self.second_value) self.form_result() def function_multiply(self): self.determinate_second_value() self.result = float(self.first_value * self.second_value) self.form_result() def function_exponentiation(self): self.determinate_second_value() self.result = float(self.first_value ** self.second_value) self.form_result() def function_percent(self): self.determinate_second_value() self.result = float(self.first_value * (self.second_value / 100)) self.form_result() def function_log(self): self.determinate_second_value() self.result = float(math.log(self.first_value, self.second_value)) self.form_result() 

La función self.determinate_second_value () determina el segundo valor de la variable que ingresamos . No es un poco lógico y torcido, pero como es, intentaré tener en cuenta todos los errores más adelante en los comentarios cuando las personas inteligentes digan cómo hacerlo.

Un pequeño refresco.

  • self.first_value: tiene el valor del primer número ingresado
  • self.equal - tiene str la variable de la operación que presionamos
  • self.second_value: tiene el valor de la segunda variable

A continuación, en cada una de las funciones de operaciones, llamamos self.form_result () , que, curiosamente, forma nuestro resultado. Mantenemos el resultado en la variable self.result .

  def form_result(self): self.result = str(self.result) if self.result[-2:] == '.0': self.result = self.result[:-2] self.lineEdit.setText(str(self.result)) self.label.clear() 

Explicaré para self.result [-2:] . [-2:] significa que estamos comparando los últimos 2 caracteres de la cadena con ".0".

Por lo tanto, nuestro resultado se muestra en el bloque principal lineEdit, felicidades.

También adjuntaré aquí un código que elimina un carácter de una cadena o el número entero o agrega "." (punto) para crear un número fraccionario:

  def make_fractional(self): value = self.lineEdit.text() if '.' not in value: self.lineEdit.setText(value + '.') def function_delete(self): value = self.lineEdit.text() self.lineEdit.setText(value[:-1]) def function_clear(self): self.lineEdit.setText('0') 

Todo el código debajo del spoiler:

Código completo
 from PySide2 import QtWidgets from calc_ui import Ui_MainWindow import sys import math class Calculator(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() #    Ui ( ) self.setupUi(self) self.show() self.lineEdit.setText('0') self.first_value = None self.second_value = None self.result = None self.example = "" self.equal = "" # pressed self.pushButton.clicked.connect(self.digit_pressed) # 1 self.pushButton_2.clicked.connect(self.digit_pressed) # 2 self.pushButton_3.clicked.connect(self.digit_pressed) # 3 self.pushButton_4.clicked.connect(self.digit_pressed) # 4 self.pushButton_5.clicked.connect(self.digit_pressed) # 5 self.pushButton_6.clicked.connect(self.digit_pressed) # 6 self.pushButton_7.clicked.connect(self.digit_pressed) # 7 self.pushButton_8.clicked.connect(self.digit_pressed) # 8 self.pushButton_9.clicked.connect(self.digit_pressed) # 9 self.pushButton_10.clicked.connect(self.digit_pressed) # 0 self.pushButton_add.clicked.connect(self.pressed_equal) # + self.pushButton_ded.clicked.connect(self.pressed_equal) # - self.pushButton_div.clicked.connect(self.pressed_equal) # / self.pushButton_mul.clicked.connect(self.pressed_equal) # * self.pushButton_exp.clicked.connect(self.pressed_equal) # ** self.pushButton_log.clicked.connect(self.pressed_equal) # log self.pushButton_procent.clicked.connect(self.pressed_equal) # % self.pushButton_ENTER.clicked.connect(self.function_result) # = self.pushButton_C.clicked.connect(self.function_clear) # C self.pushButton_point.clicked.connect(self.make_fractional) # . self.pushButton_delete.clicked.connect(self.function_delete) # < self.pushButton_open_skob.clicked.connect(self.create_big_example) # ( def digit_pressed(self): # sender - ,     (   ,    ) button = self.sender() if self.lineEdit.text() == '0': self.lineEdit.setText(button.text()) else: if self.result == self.lineEdit.text(): self.lineEdit.setText(button.text()) else: self.lineEdit.setText(self.lineEdit.text() + button.text()) self.result = 0 def form_result(self): self.result = str(self.result) if self.result[-2:] == '.0': self.result = self.result[:-2] self.lineEdit.setText(str(self.result)) self.label.clear() def make_fractional(self): value = self.lineEdit.text() if '.' not in value: self.lineEdit.setText(value + '.') def function_delete(self): value = self.lineEdit.text() self.lineEdit.setText(value[:-1]) def function_clear(self): self.lineEdit.setText('0') def pressed_equal(self): button = self.sender() self.first_value = float(self.lineEdit.text()) self.lineEdit.clear() self.label.setText(str(self.first_value) + button.text()) self.equal = button.text() def function_addition(self): self.determinate_second_value() self.result = float(self.first_value + self.second_value) self.form_result() def function_subtraction(self): self.determinate_second_value() self.result = float(self.first_value - self.second_value) self.form_result() def function_divison(self): self.determinate_second_value() self.result = float(self.first_value / self.second_value) self.form_result() def function_multiply(self): self.determinate_second_value() self.result = float(self.first_value * self.second_value) self.form_result() def function_exponentiation(self): self.determinate_second_value() self.result = float(self.first_value ** self.second_value) self.form_result() def function_percent(self): self.determinate_second_value() self.result = float(self.first_value * (self.second_value / 100)) self.form_result() def function_log(self): self.determinate_second_value() self.result = float(math.log(self.first_value, self.second_value)) self.form_result() def determinate_second_value(self): self.second_value = float(self.lineEdit.text()) self.lineEdit.clear() self.label.setText(str(self.first_value) + self.equal + str(self.second_value)) def function_result(self): if self.equal == '+': self.function_addition() elif self.equal == '-': self.function_subtraction() elif self.equal == "/": self.function_divison() elif self.equal == '*': self.function_multiply() elif self.equal == "^": self.exponentiation() elif self.equal == "%": self.function_percent() elif self.equal == "log": self.function_log() if __name__ == '__main__': #   QApplication app = QtWidgets.QApplication(sys.argv) #    calc = Calculator() #  sys.exit(app.exec_()) 


Sí, la calculadora no calcula grandes funciones y expresiones, ¡estoy trabajando en ello!

Muchas gracias por su atención Buena suerte y desarrolla! Esto es asombroso

También me gustaría invitarle a mi canal JuniorProger Telegram, donde hablo sobre la vida de un programador Junior y su forma espinosa pero muy interesante de convertirse en un especialista en informática .

Source: https://habr.com/ru/post/458536/


All Articles