Construcción de una Calculadora Completa con PyQt5 y Python

PyQt5 proporciona un conjunto robusto de herramientas para el desarrollo de interfaces gráficas de usuario (GUI) en Python. Este framework, basado en la biblioteca Qt, facilita la creación de aplicaciones multiplataforma con un aspecto profesional. A contiunación, se describe el proceso para implementar una calculadora funcional.

Configuración del Entorno

Para iniciar, se requiere la instalación de PyQt5. Utilice el gestor de paquetes pip:

pip install PyQt5

Estructura de la Aplicación

La calculadora se compone de una ventana principal con un campo de entrada para la expresión y botones para los dígitos y operaciones. La lógica principal reside en una clase que hereda de QMainWindow.

import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget,
                             QVBoxLayout, QGridLayout, QLineEdit, QPushButton)


class CalculadoraApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Calculadora PyQt5")
        self.setFixedSize(300, 400)

        # Widget central y layout
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout_principal = QVBoxLayout(central_widget)

        # Campo de visualización
        self.display = QLineEdit()
        self.display.setReadOnly(True)
        self.display.setStyleSheet("font-size: 24px; padding: 10px;")
        layout_principal.addWidget(self.display)

        # Diseño de los botones
        layout_botones = QGridLayout()
        botones = [
            ('7', 0, 0), ('8', 0, 1), ('9', 0, 2), ('/', 0, 3),
            ('4', 1, 0), ('5', 1, 1), ('6', 1, 2), ('*', 1, 3),
            ('1', 2, 0), ('2', 2, 1), ('3', 2, 2), ('-', 2, 3),
            ('0', 3, 0), ('.', 3, 1), ('=', 3, 2), ('+', 3, 3),
            ('C', 4, 0, 1, 4)  # Botón 'C' ocupa 1 fila y 4 columnas
        ]

        for datos in botones:
            texto = datos[0]
            fila = datos[1]
            columna = datos[2]
            rowspan = datos[3] if len(datos) > 3 else 1
            colspan = datos[4] if len(datos) > 4 else 1

            boton = QPushButton(texto)
            boton.setStyleSheet("font-size: 18px; padding: 15px;")
            if texto == 'C':
                boton.clicked.connect(self.limpiar_display)
            elif texto == '=':
                boton.clicked.connect(self.evaluar_expresion)
            else:
                # Usamos una lambda con un argumento predeterminado para capturar el valor
                boton.clicked.connect(lambda checked, t=texto: self.agregar_caracter(t))

            layout_botones.addWidget(boton, fila, columna, rowspan, colspan)

        layout_principal.addLayout(layout_botones)

    def agregar_caracter(self, caracter):
        texto_actual = self.display.text()
        self.display.setText(texto_actual + caracter)

    def limpiar_display(self):
        self.display.clear()

    def evaluar_expresion(self):
        expresion = self.display.text()
        try:
            # Se utiliza 'eval' con precaución; en producción, un parser seguro es preferible
            resultado = str(eval(expresion))
            self.display.setText(resultado)
        except (SyntaxError, NameError, ZeroDivisionError):
            self.display.setText("Error")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ventana = CalculadoraApp()
    ventana.show()
    sys.exit(app.exec_())

Consideraciones de Seguridad y Mejoras

El uso directo de eval() puede presentar riesgos de seguridad si la entrada del usuario no está controlada. En un entorno de producción, se recomienda implemnetar un parser matemático seguro. Asimismo, la interfaz puede enriquecerse añadiendo soporte para operaciones avanzadas como raíces cuadradas, exponentes o el historial de cálculos.

Etiquetas: PyQt5 Python gui Calculadora Desarrollo de Escritorio

Publicado el 7-12 05:50