如何用PyQt5实现一个简易计算器应用

部署运行你感兴趣的模型镜像

在本篇博客中,我将详细介绍如何使用PyQt5构建一个简易计算器应用。这个计算器能够执行基本的数学运算(如加法、减法、乘法、除法),并且能计算sincos值。用户可以通过图形界面输入数字、运算符,按下“=”按钮进行计算,还可以清空输入框,计算三角函数。

1. 项目介绍

在现代应用开发中,图形用户界面(GUI)是提升用户体验的重要部分。Python作为一门易学且功能强大的编程语言,拥有丰富的GUI开发框架,而PyQt5是其中最为流行的一种。

通过本项目,我们将创建一个简易计算器,主要功能包括:

  • 支持数字输入。

  • 支持基本的数学运算(加法、减法、乘法、除法)。

  • 支持计算sincos值(基于角度)。

  • 支持结果的显示和错误处理。

本计算器的UI设计将使用PyQt5的设计器工具来创建,而业务逻辑将由Python脚本处理。

2. 项目结构

本项目由两部分组成:

  1. UI设计部分:通过PyQt5的界面设计工具(pyuic5)生成UI界面。

  2. 功能实现部分:通过Python编写程序逻辑来处理用户输入和计算。

2.1 设计UI

首先,我们需要使用PyQt5的界面设计工具来设计UI。UI包括数字按钮、运算符按钮、清空按钮、计算按钮和输入框。我们将通过界面上的按钮来模拟用户输入,输入框(lineEdit)用于显示当前输入内容或计算结果。

设计思路:
  • 计算器界面包含数字按钮(0-9)、常用运算符(+、-、*、/)、三角函数(sin、cos)、清空按钮和计算按钮(=)。

  • 输入框用于显示用户的输入和计算结果。

通过Qt Designer生成一个UI文件,我们可以使用pyuic5将其转化为Python代码。设计的界面如下所示:

  • 顶部:标题“简易计算机”。

  • 中部:一个lineEdit,用于显示输入或结果。

  • 下方:按钮区,包括数字按钮、运算符按钮、三角函数按钮、清空按钮和计算按钮。

2.2 编写逻辑代码

UI设计完成后,我们将重点编写逻辑代码部分。主要包括以下几个功能:

  • 数字和运算符输入:点击数字按钮或运算符按钮,将按钮上的内容添加到lineEdit中。

  • 等号按钮:点击=按钮时,计算输入的数学表达式。

  • sincos按钮:点击sincos按钮时,计算输入数字的三角函数值。

  • 清空按钮:点击clean按钮时,清空输入框。

3. 步骤一:准备开发环境

3.1 安装PyQt5

在开始编写代码之前,首先需要确保已经安装了PyQt5。可以通过以下命令安装:

pip install PyQt5 

3.2 安装其他依赖

我们还需要安装math模块用于数学计算。这个模块是Python的标准库,不需要额外安装。

4. 步骤二:设计UI界面

在PyQt5中,GUI设计有两种方式:一种是通过Python代码手动布局,另一种是通过Qt Designer图形化工具设计并生成UI文件。在这里,我们使用Qt Designer来设计UI界面。

4.1 使用Qt Designer设计界面

  1. 打开Qt Designer,选择Main Window模板。

  2. 拖动并放置控件:

    • 一个QLabel用来显示标题“简易计算机”。

    • 一个QLineEdit用来显示用户输入和计算结果。

    • 多个QPushButton,分别表示数字按钮、运算符按钮、清空按钮、计算按钮等。

  3. 保存UI文件,命名为win.ui

4.2 转换为Python代码

使用PyQt5提供的工具pyuic5,将.ui文件转化为Python代码:

pyuic5 -o win.py win.ui

这样,我们就生成了win.py,它包含了UI的布局和控件。

5. 步骤三:编写逻辑代码

接下来,我们编写应用程序的逻辑部分。首先,我们需要从win.py导入UI界面,然后实现按键的功能。

5.1 继承UI类并添加功能

在新的Python脚本中,我们定义一个PyQtMainEntry类,它继承自QMainWindowUi_MainWindow。在该类中,我们实现每个按钮的点击事件,并处理输入框内容。

import math
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMainWindow
from win import Ui_MainWindow  # 导入UI类

class PyQtMainEntry(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.expression = ""  # 用来存储lineEdit的表达式

    def update_lineEdit(self, value):
        current_text = self.lineEdit.text()
        self.lineEdit.setText(current_text + value)

    # 数字和运算符按钮
    def number1(self):
        self.update_lineEdit("1")
    
    # 其他数字和运算符按钮类似...
    
    def getall(self):
        expression = self.lineEdit.text()
        try:
            result = eval(expression)  # 使用eval来计算表达式
            self.lineEdit.setText(str(result))
        except:
            self.lineEdit.setText("ERROR")  # 出现错误时显示ERROR

    def waysin(self):
        value = self.lineEdit.text()
        try:
            num = float(value)
            self.lineEdit.setText(str(math.sin(math.radians(num))))  # 计算sin值
        except:
            self.lineEdit.setText("ERROR")

    def waycos(self):
        value = self.lineEdit.text()
        try:
            num = float(value)
            self.lineEdit.setText(str(math.cos(math.radians(num))))  # 计算cos值
        except:
            self.lineEdit.setText("ERROR")

5.2 事件连接

在UI文件中,已为每个按钮定义了clicked.connect()事件。我们需要确保这些按钮与相应的功能函数连接,以便用户点击时触发正确的操作。

self.pushButton_1.clicked.connect(self.number1)  # 数字1按钮
self.pushButton_2.clicked.connect(self.number2)  # 数字2按钮
self.pushButton_15.clicked.connect(self.getall)  # 等号按钮
self.pushButton_17.clicked.connect(self.waysin)  # sin按钮
self.pushButton_18.clicked.connect(self.waycos)  # cos按钮

6. 步骤四:运行程序

在程序的最后,我们运行QApplication事件循环,启动计算器应用:

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = PyQtMainEntry()
    window.show()
    sys.exit(app.exec_())

7.完整代码展示

win.py:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'win.ui'
#
# Created by: PyQt5 UI code generator 5.15.11
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(240, 40, 271, 51))
        self.label.setStyleSheet("font: 40pt \"Agency FB\";")
        self.label.setObjectName("label")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(180, 130, 391, 51))
        self.lineEdit.setStyleSheet("font: 24pt \"Agency FB\";")
        self.lineEdit.setObjectName("lineEdit")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(110, 240, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(230, 240, 75, 23))
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(360, 240, 75, 23))
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_4.setGeometry(QtCore.QRect(110, 290, 75, 23))
        self.pushButton_4.setObjectName("pushButton_4")
        self.pushButton_5 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_5.setGeometry(QtCore.QRect(230, 290, 75, 23))
        self.pushButton_5.setObjectName("pushButton_5")
        self.pushButton_6 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_6.setGeometry(QtCore.QRect(360, 290, 75, 23))
        self.pushButton_6.setObjectName("pushButton_6")
        self.pushButton_7 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_7.setGeometry(QtCore.QRect(110, 340, 75, 23))
        self.pushButton_7.setObjectName("pushButton_7")
        self.pushButton_8 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_8.setGeometry(QtCore.QRect(230, 340, 75, 23))
        self.pushButton_8.setObjectName("pushButton_8")
        self.pushButton_9 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_9.setGeometry(QtCore.QRect(360, 340, 75, 23))
        self.pushButton_9.setObjectName("pushButton_9")
        self.pushButton_10 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_10.setGeometry(QtCore.QRect(110, 400, 75, 23))
        self.pushButton_10.setObjectName("pushButton_10")
        self.pushButton_11 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_11.setGeometry(QtCore.QRect(480, 290, 75, 23))
        self.pushButton_11.setObjectName("pushButton_11")
        self.pushButton_12 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_12.setGeometry(QtCore.QRect(480, 350, 75, 23))
        self.pushButton_12.setObjectName("pushButton_12")
        self.pushButton_13 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_13.setGeometry(QtCore.QRect(480, 240, 75, 23))
        self.pushButton_13.setObjectName("pushButton_13")
        self.pushButton_14 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_14.setGeometry(QtCore.QRect(590, 290, 75, 23))
        self.pushButton_14.setObjectName("pushButton_14")
        self.pushButton_15 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_15.setGeometry(QtCore.QRect(590, 350, 75, 23))
        self.pushButton_15.setObjectName("pushButton_15")
        self.pushButton_16 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_16.setGeometry(QtCore.QRect(480, 400, 75, 23))
        self.pushButton_16.setObjectName("pushButton_16")
        self.pushButton_17 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_17.setGeometry(QtCore.QRect(230, 400, 75, 23))
        self.pushButton_17.setObjectName("pushButton_17")
        self.pushButton_18 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_18.setGeometry(QtCore.QRect(360, 400, 75, 23))
        self.pushButton_18.setObjectName("pushButton_18")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.pushButton_14.clicked.connect(self.lineEdit.clear) # type: ignore
        self.pushButton_2.clicked.connect(MainWindow.number2) # type: ignore
        self.pushButton_3.clicked.connect(MainWindow.number3) # type: ignore
        self.pushButton.clicked.connect(MainWindow.number1) # type: ignore
        self.pushButton_4.clicked.connect(MainWindow.number4) # type: ignore
        self.pushButton_5.clicked.connect(MainWindow.number5) # type: ignore
        self.pushButton_6.clicked.connect(MainWindow.number6) # type: ignore
        self.pushButton_7.clicked.connect(MainWindow.number7) # type: ignore
        self.pushButton_8.clicked.connect(MainWindow.number8) # type: ignore
        self.pushButton_9.clicked.connect(MainWindow.number9) # type: ignore
        self.pushButton_10.clicked.connect(MainWindow.number0) # type: ignore
        self.pushButton_15.clicked.connect(MainWindow.getall) # type: ignore
        self.pushButton_13.clicked.connect(MainWindow.way1) # type: ignore
        self.pushButton_11.clicked.connect(MainWindow.way2) # type: ignore
        self.pushButton_12.clicked.connect(MainWindow.way3) # type: ignore
        self.pushButton_16.clicked.connect(MainWindow.way4) # type: ignore
        self.pushButton_18.clicked.connect(MainWindow.waycos) # type: ignore
        self.pushButton_17.clicked.connect(MainWindow.waysin) # type: ignore
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "简易计算机"))
        self.pushButton.setText(_translate("MainWindow", "1"))
        self.pushButton_2.setText(_translate("MainWindow", "2"))
        self.pushButton_3.setText(_translate("MainWindow", "3"))
        self.pushButton_4.setText(_translate("MainWindow", "4"))
        self.pushButton_5.setText(_translate("MainWindow", "5"))
        self.pushButton_6.setText(_translate("MainWindow", "6"))
        self.pushButton_7.setText(_translate("MainWindow", "7"))
        self.pushButton_8.setText(_translate("MainWindow", "8"))
        self.pushButton_9.setText(_translate("MainWindow", "9"))
        self.pushButton_10.setText(_translate("MainWindow", "0"))
        self.pushButton_11.setText(_translate("MainWindow", "-"))
        self.pushButton_12.setText(_translate("MainWindow", "*"))
        self.pushButton_13.setText(_translate("MainWindow", "+"))
        self.pushButton_14.setText(_translate("MainWindow", "clean"))
        self.pushButton_15.setText(_translate("MainWindow", "="))
        self.pushButton_16.setText(_translate("MainWindow", "/"))
        self.pushButton_17.setText(_translate("MainWindow", "sin"))
        self.pushButton_18.setText(_translate("MainWindow", "cos"))

main.py(主函数)

import math

from PyQt5 import QtCore, QtGui, QtWidgets  # 导入PyQt5的主要模块
from PyQt5.QtCore import *                 # 导入QtCore模块的所有内容,用于核心功能
from PyQt5.QtGui import *                  # 导入QtGui模块的所有内容,用于图形功能
from PyQt5.QtWidgets import QFileDialog, QMainWindow, QMessageBox  # 导入QtWidgets模块中的一些特定类
'''QFileDialog可以帮助用户选择文件路径
QMainWindow则是创建具有菜单、工具栏和状态栏的主窗口的起点。
QMessageBox可以用于向用户显示提示或警告信息'''

from win import Ui_MainWindow  # 导入UI类,这个类包含了你的主窗口设计
import sys   # 导入系统模块,用于访问命令行参数和系统相关功能


# 导入 math 库用于数学计算
class PyQtMainEntry(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.expression = ""  # 用来存储lineEdit的表达式

    # 更新lineEdit内容(用于按钮点击)
    def update_lineEdit(self, value):
        current_text = self.lineEdit.text()
        self.lineEdit.setText(current_text + value)

    # 处理数字和运算符按钮点击
    def number1(self):
        self.update_lineEdit("1")

    def number2(self):
        self.update_lineEdit("2")

    def number3(self):
        self.update_lineEdit("3")

    def number4(self):
        self.update_lineEdit("4")

    def number5(self):
        self.update_lineEdit("5")

    def number6(self):
        self.update_lineEdit("6")

    def number7(self):
        self.update_lineEdit("7")

    def number8(self):
        self.update_lineEdit("8")

    def number9(self):
        self.update_lineEdit("9")

    def number0(self):
        self.update_lineEdit("0")

    def way1(self):  # 加号按钮
        self.update_lineEdit("+")

    def way2(self):  # 减号按钮
        self.update_lineEdit("-")

    def way3(self):  # 乘号按钮
        self.update_lineEdit("*")

    def way4(self):  # 除号按钮
        self.update_lineEdit("/")

    # 清空lineEdit内容
    def clear(self):
        self.lineEdit.clear()

    # 计算表达式结果
    def getall(self):
        expression = self.lineEdit.text()
        try:
            result = eval(expression)  # 使用eval来计算表达式
            self.lineEdit.setText(str(result))
        except:
            self.lineEdit.setText("ERROR")  # 出现错误时显示ERROR

    # 计算sin值(仅适用于纯数字)
    def waysin(self):
        value = self.lineEdit.text()
        try:
            num = float(value)
            self.lineEdit.setText(str(math.sin(math.radians(num))))  # 将角度转换为弧度并计算sin
        except:
            self.lineEdit.setText("ERROR")

    # 计算cos值(仅适用于纯数字)
    def waycos(self):
        value = self.lineEdit.text()
        try:
            num = float(value)
            self.lineEdit.setText(str(math.cos(math.radians(num))))  # 将角度转换为弧度并计算cos
        except:
            self.lineEdit.setText("ERROR")


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)  # 创建应用程序实例
    window = PyQtMainEntry()  # 创建主窗口实例
    window.show()  # 显示主窗口
    sys.exit(app.exec_())  # 进入事件循环,并确保在退出时清理

8. 总结

通过本篇博客,我们从思路到操作步骤,详细介绍了如何使用PyQt5实现一个简易计算器。该计算器支持数字输入、基本运算、三角函数计算以及错误处理。整个开发过程从UI设计到功能实现都进行了详细讲解,帮助大家了解如何用PyQt5开发简单的GUI应用。

如果你已经掌握了这些基本操作,后续可以尝试更复杂的功能和设计,比如增加内存功能、支持多步计算、或者加入更多的数学函数等。希望这篇博客能为你开发GUI应用提供一些启发!

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值