PyQt6制作简易计算器完整代码

使用 PyQt6 制作一个简易计算器,支持加减乘除、小数点、百分号等基本操作,现分享完整代码,环境一致可直接运行。

运行环境:Python3.10,PyQt6版本为 6.4.2。

参考:PyQt5做计算器(详细讲解, 绝对让你学会)-CSDN博客

运行展示

由于是用 eval 函数计算的,所以复刻了计算机科学领域经典 bug:0.1+0.2不等于0.3,使用try/except语句捕获异常,避免崩溃。

完整代码

1. 导入库及构建计算器类

from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QWidget, QSizePolicy, QGridLayout, QPushButton, QApplication, QTextEdit
import sys


class Calculator(QWidget):

    def __init__(self):
        super(Calculator, self).__init__()
        self.minwh = 240, 240
        self.setMinimumSize(self.minwh[0], self.minwh[1])
        self.resize(self.minwh[0], self.minwh[1])
        
        self.ui()
        self.operators = '+-*/∓%.'  # 用于判断按钮的值是不是操作符
        self.numbers = '0123456789'  # 用于判断按钮的值是不是数字
        self.last_oper_flag = False  # 上次按钮是否为操作符
        self.complete = True  # 计算完成状态
        self.values = ['0']  # 储存数字
        self.operas = []  # 储存操作符

 2. 设计界面

    def ui(self):
        # 初始化界面, self.text_edit 即计算器的屏幕
        self.text_edit = QTextEdit('0', self)
        self.text_edit.setReadOnly(True)
        self.text_edit.setMinimumHeight(40)
        self.text_edit.setMaximumHeight(40)
        self.text_edit.setAlignment(Qt.AlignmentFlag.AlignRight)
        self.text_edit.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
        
        grid = QGridLayout(self)  # 使用girdlayout进行界面布局
        
        btn_names = [
            'C', '<', '%', '/',
            '7', '8', '9', '*',
            '4', '5', '6', '-',
            '1', '2', '3', '+',
            '∓', '0', '.', '='
        ]
        
        grid.addWidget(self.text_edit, 0, 0, 1, 4)
        positions = [(i, j) for i in range(1, 6) for j in range(4)]
        for pos, name in zip(positions, btn_names):
            btn = QPushButton(name, self)
            btn.clicked.connect(self.fun)  # 把每个按钮连接到点击事件上
            btn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
            grid.addWidget(btn, *pos)
        self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
        self.setWindowTitle('Calculator')
        self.show()

3. 按下按钮后执行的函数

    def fun(self):
        sender = self.sender()
        btn_text = sender.text()
        if btn_text == '=':  # 点击 =
            if not self.complete:  # 计算结果
                self.compute()
            # else: pass  # 计算已完成则不执行操作
        else:
            if btn_text == 'C':  # 点击 C
                self.refresh()
            elif btn_text == '<':  # 点击 <
                self.delete()
            elif btn_text in self.numbers:  # 点击数字
                self.f_number(btn_text)
            else:  # 点击操作符
                self.f_operta(btn_text)

4. 按下 C 按钮归零计算器

    def refresh(self):
        self.values = ['0']
        self.operas = []
        self.last_oper_flag = False
        self.text_edit.setText('0')
        self.text_edit.setAlignment(Qt.AlignmentFlag.AlignRight)

5. 按下 DELETE 按钮执行的函数

    def delete(self):
        if self.complete:  # 计算已完成则归零
            self.refresh()
        else:
            # 最后一个数字只有一位数字或一个 (-x) 就去除最后一个数字
            if len(self.values[-1]) == 1 or len(self.values[-1]) == 4 and self.values[-1].startswith('(-'):
                self.values.pop()
                if len(self.operas) > 0:  # 去除最后一个操作符
                    self.operas.pop()
            # 删除最后一个数字的最后一个字符
            elif self.values[-1].endswith(')'):  # 最后一个数字含括号
                self.values[-1] = self.values[-1][:-2] + ')'
            else:  # 最后一个数字不含括号
                self.values[-1] = self.values[-1][:-1]

            # 储存的数字已被清空则归零
            if len(self.values) == 0:
                self.refresh()
            self.rend()

6. 按下数字按钮执行的函数

    def f_number(self, btn_text):
        if self.complete:
            self.complete = False
        if self.last_oper_flag:  # 上次按了操作符则正常添加数字
            self.values.append(btn_text)
        else:  # 上次为添加数字
            if len(self.values[-1]) == 1 and self.values[-1] == '0':  # 最后一个数只有一个0, 去掉0再添加数字
                self.values[-1] = self.values[-1][:-1] + btn_text
            elif self.values[-1][-1] == ')':  # 最后有括号, 在 ) 前添加数字
                self.values[-1] = self.values[-1][:-1] + btn_text + ')'
            else:  # 正常添加数字
                self.values[-1] = self.values[-1] + btn_text
        self.last_oper_flag = False
        self.rend()

 7. 按下操作符按钮执行的函数

    def f_operta(self, btn_text):
        if self.last_oper_flag:  # 上次按了 +-*/ 则无视上次操作
            self.last_oper_flag = False
            self.operas.pop()
        if btn_text == '∓':  # 最后一个数字乘以-1
            value = eval('-' + self.values[-1])
            if value < 0:  # 若结果为负, 则用括号包围
                self.values[-1] = '(' + str(value) + ')'
            else:
                self.values[-1] = str(value)
        elif btn_text == '%':  # 最后一个数字乘以0.01
            value = eval('0.01*' + self.values[-1])
            self.values[-1] = str(value)
        elif btn_text == '.':  # 最后一个数字添加小数点
            if not '.' in self.values[-1]:  # 最后一个数字不含小数点
                if self.values[-1][-1] == ')':  # 最后一个数字含括号, 在 ) 前添加小数点
                    self.values[-1] = self.values[-1][:-1] + '.' + ')'
                else:  # 正常添加小数点
                    self.values[-1] += '.'
        else:  # 本次按了 +-*/
            self.last_oper_flag = True
            self.operas.append(btn_text)
        self.rend()

8. 按下 = 按钮执行计算

    def compute(self):
        text = self.get_text()
        try:
            result = str(eval(text))
        except Exception as e:
            result = 'Error: ' + str(e) + '!'
        text = text + ' = \n' + result
        self.text_edit.setText(text)
        self.text_edit.setAlignment(Qt.AlignmentFlag.AlignRight)
        self.values = ['0']
        self.operas = []
        self.last_oper_flag = False
        self.complete = True

9. 屏显及自适应缩放

    def get_text(self):
        # 获得屏幕显示字符
        n = len(self.values)
        text = ''
        for i in range(n):
            text += self.values[i]
            if i < n - 1:
                text += ' ' + self.operas[i] + ' '
        return text
    
    def rend(self):
        # 在屏幕上显示字符
        text = self.get_text()
        self.text_edit.setText(text)
        self.text_edit.setAlignment(Qt.AlignmentFlag.AlignRight)
    
    def resizeMainWindow(self):
        # 自适应缩放
        self.adjustSize()

 10. 运行程序

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Calculator()
    sys.exit(app.exec())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值