pyqt5栅格布局计算器

pyqt5 计算器

自己随便写写的,有完整注释,不单单是为了实现,而是尽可能完美
虽然还有不少bug
实现连续运算,退位等操作

ui按钮部分由https://github.com/maicss/PyQt5-Chinese-tutorial提供
原文并没有提供对栅格布局操作,我做的就是添加一个显示屏
然后对按钮信号处理,实现计算器

有bug可以提,但是我肯定懒得改,除非你告诉我怎么改

代码源

import sys
from PyQt5.QtWidgets import (QWidget, QGridLayout, QLCDNumber, QVBoxLayout,QMessageBox,
                             QPushButton, QApplication)

"""
栅格布局是一种特定的写法,通过位置来确定部件的方位,
[(0, 0 ), (0, 1 ), (0, 2 )
 (1, 0 ), (1, 1 ), (1, 2 )
 (2, 0 ), (2, 1 ), (2, 2 )]
 以元组形式依次对其中的部件进行定义,可以用for循环,也可以自己一个个导入
以下写入的
button = QPushButton(name)  # 需要写入的部件
grid.addWidget(button, *position
"""
class Example(QWidget):

    def __init__(self):
        super().__init__()
        self.init_all()  # 初始化数据
        self.initUI()  # ui

    def init_all(self):
        self.list_number_0 = str()
        self.list_number_1 = str()
        self.max_len_number = 7
        self.Operator_equal = False
        self.Operator = ''


    def initUI(self):

        vbox = QVBoxLayout()
        grid = QGridLayout()  # 构建栅格布局
        self.led = QLCDNumber(self)
        self.led.setDigitCount(self.max_len_number)
        self.led.setSegmentStyle(QLCDNumber.Filled)

        names = ['Cls', 'Bck', '', 'Close',
                 '7', '8', '9', '/',
                 '4', '5', '6', '*',
                 '1', '2', '3', '-',
                 '0', '.', '=', '+']

        positions = [(i, j) for i in range(5) for j in range(4)]  # 构建四行五列的表格
        for position, name in zip(positions, names):
            if name == '':
                continue
            button = QPushButton(name)  # 生成按钮添加在特定位置中,只在栅格布局中可以这样用
            grid.addWidget(button, *position)  # 并未设置信号槽机制
            button.clicked.connect(self.button_clicked)

        vbox.addWidget(self.led)
        vbox.addLayout(grid)
        self.setLayout(vbox)
        self.resize(400, 300)
        self.move(300, 150)
        self.setWindowTitle('Calculator')
        self.show()

    def button_clicked(self):
        source = self.sender().text()  # 获取触发按键命名
        if source.isnumeric():  # 判断命名是否为数字
            if self.Operator == '':  # 判断处理的是第一个数还是第二个数
                if len(self.list_number_0) < self.max_len_number:  # 限制输入的位数,可以通过接口直接改变
                    if self.list_number_0 != '0':  # 防止出现显示0001情况,不用float是因为为了后面小数点时不显示问题(为了美观)
                        self.list_number_0 += source  # 添加数字在第一个数后面
                        self.led.display(self.list_number_0)  # 显示数字
            else:  # 第二个数处理
                if len(self.list_number_1) < self.max_len_number:
                    if self.list_number_1 != '0':
                        self.list_number_1 += source
                        self.led.display(self.list_number_1)

        if source == '+' or source == '-' or source == '/' or source == '*':  # 可以不通过等于号获取结果,进行连续运算
            if self.list_number_1:  # 只要第二个数存在
                if self.Operator == '+':  # 按照运算符直接获取结果
                    value = float(self.list_number_0) + float(self.list_number_1)
                    self.led.display(value)
                elif self.Operator == '-':
                    value = float(self.list_number_0) - float(self.list_number_1)
                    self.led.display(value)
                elif self.Operator == '*':
                    value = float(self.list_number_0) * float(self.list_number_1)
                    self.led.display(value)
                else:
                    if self.list_number_1 != '0':  # 分母为0就弹出提示窗口
                        value = float(self.list_number_0) / float(self.list_number_1)
                        self.led.display(value)
                    else:
                        self.equal_0()
                        value = 0
                self.list_number_0 = str(value)  # 最后将数据赋值给第一个数,进行下一次运算
            self.list_number_1 = str()
            self.Operator_equal = True  # 开启
            self.Operator = source  # 获取运算符

        if source == '.':  # 小数点处理
            if not self.Operator_equal:  # 判断第一个还是第二个
                self.list_number_0 = str(self.led.value())[:-1]
                self.led.display(self.list_number_0)
            else:
                self.list_number_1 = str(self.led.value())[:-1]
                self.led.display(self.list_number_1)

        if source == '=':  # 等号运算
            if self.list_number_1 != '':  # 如果第二个值未出现不做任何操作
                if self.Operator == '':  # 判断是否存在第二个数
                    self.led.display(self.list_number_0)
                else:
                    if self.Operator == '+':  # 运算
                        value = float(self.list_number_0) + float(self.list_number_1)
                        self.led.display(value)
                    elif self.Operator == '-':
                        value = float(self.list_number_0) - float(self.list_number_1)
                        self.led.display(value)
                    elif self.Operator == '*':
                        value = float(self.list_number_0) * float(self.list_number_1)
                        self.led.display(value)
                    else:
                        if self.list_number_1 != '0':  # 分母处理
                            value = float(self.list_number_0) / float(self.list_number_1)
                            self.led.display(value)
                        else:
                            self.equal_0()  # 分母报错提示
                            value = 0
                    self.list_number_0 = str(value)
            self.Operator_equal = True

        if source == 'Bck':  # 退位处理
            if self.Operator_equal:  # 第二个数字不等于空
                if len(self.list_number_0) <= 1:  # 如果位数小于1就显示0并且初始化
                    self.list_number_0 = str()
                    self.led.display('0')
                else:
                    if self.list_number_0[-2] == '.':  # 如果小数点存在倒数第二位就把小数点和最后一位数一起删掉
                        self.list_number_0 = self.list_number_0[:-2] + self.list_number_0[-1]  # 也可以不删,但是为了美观
                    self.list_number_0 = self.list_number_0[:-1]
                    self.led.display(self.list_number_0)
            else:
                if self.Operator == '+' or self.Operator == '-' or self.Operator == '*' or self.Operator == '/':
                    if len(self.list_number_1) <= 1:
                        self.list_number_1 = str()
                        self.led.display('0')
                    else:
                        if self.list_number_1[-2] == '.':
                            self.list_number_1 = self.list_number_1[:-2] + self.list_number_1[-1]
                        self.list_number_1 = self.list_number_1[:-1]
                        self.led.display(self.list_number_1)
                else:
                    if len(self.list_number_0) <= 1:
                        self.list_number_0 = str()
                        self.led.display('0')
                    else:
                        if self.list_number_0[-2] == '.':
                            self.list_number_0 = self.list_number_0[:-2] + self.list_number_0[-1]
                        self.list_number_0 = self.list_number_0[:-1]
                        self.led.display(self.list_number_0)

        if source == 'Close':  # 关闭按钮
            self.close()
        if source == 'Cls':
            self.init_all()  # 全部请0
            self.led.display('0')

    def equal_0(self):  # 分母不为0
        reply = QMessageBox.question(self, 'Message', f"分母不得为0",
                                     QMessageBox.Retry, QMessageBox.Retry)  # 弹出窗口游戏结算
        if reply == QMessageBox.Close:  # 信号判断
            self.close()  # 选择关闭
        else:
            self.init_all()  # 选择重新开始
            self.led.display('0')


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

实现的不是那么好,写到后期发现实际上可以利用显示屏的.value()和.text()来回横跳,但是以欲罢不能了,有兴趣的同学可以沿着这条思路实现,让代码变得更简洁

不可转载

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值