当前位置: 首页 > news >正文

如何用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")  # 出现错误时显示ERRORdef 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, QtWidgetsclass 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: ignoreself.pushButton_2.clicked.connect(MainWindow.number2) # type: ignoreself.pushButton_3.clicked.connect(MainWindow.number3) # type: ignoreself.pushButton.clicked.connect(MainWindow.number1) # type: ignoreself.pushButton_4.clicked.connect(MainWindow.number4) # type: ignoreself.pushButton_5.clicked.connect(MainWindow.number5) # type: ignoreself.pushButton_6.clicked.connect(MainWindow.number6) # type: ignoreself.pushButton_7.clicked.connect(MainWindow.number7) # type: ignoreself.pushButton_8.clicked.connect(MainWindow.number8) # type: ignoreself.pushButton_9.clicked.connect(MainWindow.number9) # type: ignoreself.pushButton_10.clicked.connect(MainWindow.number0) # type: ignoreself.pushButton_15.clicked.connect(MainWindow.getall) # type: ignoreself.pushButton_13.clicked.connect(MainWindow.way1) # type: ignoreself.pushButton_11.clicked.connect(MainWindow.way2) # type: ignoreself.pushButton_12.clicked.connect(MainWindow.way3) # type: ignoreself.pushButton_16.clicked.connect(MainWindow.way4) # type: ignoreself.pushButton_18.clicked.connect(MainWindow.waycos) # type: ignoreself.pushButton_17.clicked.connect(MainWindow.waysin) # type: ignoreQtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.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 mathfrom 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))))  # 将角度转换为弧度并计算sinexcept: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))))  # 将角度转换为弧度并计算cosexcept: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应用提供一些启发!

http://www.dtcms.com/a/540488.html

相关文章:

  • Spring Boot 事务管理深度解析
  • 【系统分析师】高分论文:软件的系统测试及应用(电子商务门户网站系统)
  • 尚硅谷React扩展笔记
  • 8.模板和string(下)
  • 5G专网客户案例分享:基于可编程5G的工业互联网产线验证系统
  • 前端:前端开发中,实现水印(Watermark)
  • 网站排名方法胶州网站建设 网络推广
  • 潍坊商城网站建设修改wordpress样式
  • AI智能体从系统智能到生态智能:SmartMediaKit 如何成为智能体时代的视频神经系统
  • 【音视频】H.264关键帧识别
  • AI智能相机未来应用
  • grafana做状态变化的监控图表
  • 19.高级的ACL
  • 网站推广广告营销方案海南省建设培训网站报名
  • Excel怎么根据居民身份证号码获取性别?
  • 张家港网站设计织梦网站文章发布模板下载
  • 在Ubuntu通过命令行安装MySQL(tabby远程)
  • 【JavaEE初阶】网络原理——TCP核心机制2 超时重传
  • 电科金仓推动浙人医信创发展:多院区异构数据库架构的创新解决方案
  • 【JavaEE初阶】TCP核心机制3——连接管理
  • 找工作在什么网站找比较好南京市浦口区城乡建设局网站
  • Matter协议,如何塑造更宜居、流畅的智能家居网络?
  • git config --global user.name
  • 如何为直播视频APP选择合适的高防产品
  • 探索Perplexity:当AI遇上搜索引擎的革命性突破
  • macOS 部署安装 IndexTTS2
  • 缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题
  • 【软件架构】数据库系统与缓存设计:五种缓存一致性方案
  • 什么样的网站是一个成功的网站如何介绍网站模板
  • 广西网站建设推广报价wordpress纯图片主题