《老鸟python 系列》视频上线了,全网稀缺资源,涵盖python人工智能教程,爬虫教程,web教程,数据分析教程以及界面库和服务器教程,以及各个方向的主流实用项目,手把手带你从零开始进阶高手之路!点击 链接 查看详情




精品计算器

阅读:223397835    分享到

本节课,我们以所学的 Qt 的知识,来编写一个精品计算器的项目,计算器虽然是一个小项目,我们也要遵循软件工程的步骤。

项目设计

可行性分析:我们用 PyQt 界面库完全可以胜任开发一个带图形界面的计算器。

需求分析:实现用户点击数字进行四则运算。

设计:用 Qt Designer 进行 UI 设计,计算逻辑放在一个类里面设计。

代码编写:先用 QtDesigner 设计 UI 界面,然后转化为 py 代码,然后再写一个计算器类,该类关联上 UI 并在该类里面做计算逻辑处理。

测试:我们用开发好的计算器程序进行四则运算测试。

运行与维护:最后交付给客户始运行维护。

项目编写

首先,我们用 Qt Designer 设计一个基于 QWidget 的计算器界面,如下图所示。

我们把生成的 ui 文件转为 py 文件后,精品计算器的界面代码如下,在 Qt Designer 里面,我只设计了控件以及控件上面字体的大小。

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

# Form implementation generated from reading ui file 'mytest.ui'
#
# Created by: PyQt5 UI code generator 5.15.1
#
# 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_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(527, 629)
        self.pushButton_clear = QtWidgets.QPushButton(Form)
        self.pushButton_clear.setGeometry(QtCore.QRect(20, 90, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_clear.setFont(font)
        self.pushButton_clear.setObjectName("pushButton_clear")
        self.lineEdit_rst = QtWidgets.QLineEdit(Form)
        self.lineEdit_rst.setGeometry(QtCore.QRect(20, 10, 481, 61))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.lineEdit_rst.setFont(font)
        self.lineEdit_rst.setObjectName("lineEdit_rst")
        self.pushButton_link = QtWidgets.QPushButton(Form)
        self.pushButton_link.setGeometry(QtCore.QRect(150, 90, 351, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_link.setFont(font)
        self.pushButton_link.setCheckable(False)
        self.pushButton_link.setObjectName("pushButton_link")
        self.pushButton_7 = QtWidgets.QPushButton(Form)
        self.pushButton_7.setGeometry(QtCore.QRect(20, 200, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_7.setFont(font)
        self.pushButton_7.setObjectName("pushButton_7")
        self.pushButton_9 = QtWidgets.QPushButton(Form)
        self.pushButton_9.setGeometry(QtCore.QRect(280, 200, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_9.setFont(font)
        self.pushButton_9.setObjectName("pushButton_9")
        self.pushButton_8 = QtWidgets.QPushButton(Form)
        self.pushButton_8.setGeometry(QtCore.QRect(150, 200, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_8.setFont(font)
        self.pushButton_8.setObjectName("pushButton_8")
        self.pushButton_divide = QtWidgets.QPushButton(Form)
        self.pushButton_divide.setGeometry(QtCore.QRect(410, 200, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_divide.setFont(font)
        self.pushButton_divide.setObjectName("pushButton_divide")
        self.pushButton_multiply = QtWidgets.QPushButton(Form)
        self.pushButton_multiply.setGeometry(QtCore.QRect(410, 310, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_multiply.setFont(font)
        self.pushButton_multiply.setObjectName("pushButton_multiply")
        self.pushButton_4 = QtWidgets.QPushButton(Form)
        self.pushButton_4.setGeometry(QtCore.QRect(20, 310, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_4.setFont(font)
        self.pushButton_4.setObjectName("pushButton_4")
        self.pushButton_6 = QtWidgets.QPushButton(Form)
        self.pushButton_6.setGeometry(QtCore.QRect(280, 310, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_6.setFont(font)
        self.pushButton_6.setObjectName("pushButton_6")
        self.pushButton_5 = QtWidgets.QPushButton(Form)
        self.pushButton_5.setGeometry(QtCore.QRect(150, 310, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_5.setFont(font)
        self.pushButton_5.setObjectName("pushButton_5")
        self.pushButton_2 = QtWidgets.QPushButton(Form)
        self.pushButton_2.setGeometry(QtCore.QRect(150, 430, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_2.setFont(font)
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_1 = QtWidgets.QPushButton(Form)
        self.pushButton_1.setGeometry(QtCore.QRect(20, 430, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_1.setFont(font)
        self.pushButton_1.setObjectName("pushButton_1")
        self.pushButton_minus = QtWidgets.QPushButton(Form)
        self.pushButton_minus.setGeometry(QtCore.QRect(410, 430, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_minus.setFont(font)
        self.pushButton_minus.setObjectName("pushButton_minus")
        self.pushButton_3 = QtWidgets.QPushButton(Form)
        self.pushButton_3.setGeometry(QtCore.QRect(280, 430, 91, 81))
        font = QtGui.QFont()
        font.setFamily("Agency FB")
        font.setPointSize(22)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton_3.setFont(font)
        self.pushButton_3.setIconSize(QtCore.QSize(18, 18))
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_dot = QtWidgets.QPushButton(Form)
        self.pushButton_dot.setGeometry(QtCore.QRect(150, 530, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_dot.setFont(font)
        self.pushButton_dot.setObjectName("pushButton_dot")
        self.pushButton_0 = QtWidgets.QPushButton(Form)
        self.pushButton_0.setGeometry(QtCore.QRect(20, 530, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_0.setFont(font)
        self.pushButton_0.setObjectName("pushButton_0")
        self.pushButton_plus = QtWidgets.QPushButton(Form)
        self.pushButton_plus.setGeometry(QtCore.QRect(410, 530, 91, 81))
        font = QtGui.QFont()
        font.setPointSize(22)
        self.pushButton_plus.setFont(font)
        self.pushButton_plus.setObjectName("pushButton_plus")
        self.pushButton_rst = QtWidgets.QPushButton(Form)
        self.pushButton_rst.setGeometry(QtCore.QRect(280, 530, 91, 81))
        font = QtGui.QFont()
        font.setFamily("Agency FB")
        font.setPointSize(22)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_rst.setFont(font)
        self.pushButton_rst.setIconSize(QtCore.QSize(18, 18))
        self.pushButton_rst.setObjectName("pushButton_rst")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "精品计算器"))
        self.pushButton_clear.setText(_translate("Form", "AC"))
        self.pushButton_link.setText(_translate("Form", "www.birdpython.com"))
        self.pushButton_7.setText(_translate("Form", "7"))
        self.pushButton_9.setText(_translate("Form", "9"))
        self.pushButton_8.setText(_translate("Form", "8"))
        self.pushButton_divide.setText(_translate("Form", "÷"))
        self.pushButton_multiply.setText(_translate("Form", "×"))
        self.pushButton_4.setText(_translate("Form", "4"))
        self.pushButton_6.setText(_translate("Form", "6"))
        self.pushButton_5.setText(_translate("Form", "5"))
        self.pushButton_2.setText(_translate("Form", "2"))
        self.pushButton_1.setText(_translate("Form", "1"))
        self.pushButton_minus.setText(_translate("Form", "-"))
        self.pushButton_3.setText(_translate("Form", "3"))
        self.pushButton_dot.setText(_translate("Form", "."))
        self.pushButton_0.setText(_translate("Form", "0"))
        self.pushButton_plus.setText(_translate("Form", "+"))
        self.pushButton_rst.setText(_translate("Form", "="))

设计好界面之后,然后我创建一个继承 Qwidget 的类,在该类里面做计算逻辑处理,信号槽,关联 UI 界面,设置界面属性,以及对界面上的控件设置背景色等操作。

import sys
import calui
from decimal import Decimal
from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QIcon, QPalette, QBrush, QPixmap

class MyWidget(QWidget):
    def initdata(self):      # 初始化数据
        self.operator = ""   # 运算符
        self.leftdata = ""   # 左边数据
        self.rightdata = ""  # 右边数据
        self.bcalculated = False  # 有没有做运算
        self.error = False  # 错误的计算,比如除数为0

    def initui(self):
        self.setFixedSize(self.width(), self.height())  # 设置窗口固定大小
        self.setWindowIcon(QIcon('birdpython.png'))     # 设置窗口图标
        self.ui.lineEdit_rst.setText("0")  # 结果栏里默认为 0

        # 给窗口设置背景图片
        palette = QPalette()
        palette.setBrush(QPalette.Background, QBrush(QPixmap("background.png")))
        self.setPalette(palette)

        # 给链接按钮设置颜色
        self.ui.pushButton_link.setStyleSheet('QPushButton {background-color: green}')

    def __init__(self):
        self.initdata()
        super(MyWidget, self).__init__()
        self.ui = calui.Ui_Form()
        self.ui.setupUi(self)
        self.initui()

        # 数字信号槽关联
        self.ui.pushButton_1.clicked.connect(self.clicked_num)
        self.ui.pushButton_2.clicked.connect(self.clicked_num)
        self.ui.pushButton_3.clicked.connect(self.clicked_num)
        self.ui.pushButton_4.clicked.connect(self.clicked_num)
        self.ui.pushButton_5.clicked.connect(self.clicked_num)
        self.ui.pushButton_6.clicked.connect(self.clicked_num)
        self.ui.pushButton_7.clicked.connect(self.clicked_num)
        self.ui.pushButton_8.clicked.connect(self.clicked_num)
        self.ui.pushButton_9.clicked.connect(self.clicked_num)
        self.ui.pushButton_0.clicked.connect(self.clicked_num)

        # 运算
        self.ui.pushButton_plus.clicked.connect(self.clicked_calculate)
        self.ui.pushButton_minus.clicked.connect(self.clicked_calculate)
        self.ui.pushButton_multiply.clicked.connect(self.clicked_calculate)
        self.ui.pushButton_divide.clicked.connect(self.clicked_calculate)

        # 官网
        self.ui.pushButton_link.clicked.connect(self.clicked_link)

        # 归零
        self.ui.pushButton_clear.clicked.connect(self.clicked_clear)

        # 小数点
        self.ui.pushButton_dot.clicked.connect(self.clicked_dot)

        # 等号
        self.ui.pushButton_rst.clicked.connect(self.clicked_result)

    def clicked_link(self):
        QtGui.QDesktopServices.openUrl(QtCore.QUrl('http://www.birdpython.com'))

    def clicked_dot(self):  # 小数点
        if self.bcalculated == True:  # 右边数
            if self.rightdata == "":
                self.rightdata = "0."
            else:
                self.rightdata += "."
            self.ui.lineEdit_rst.setText(self.rightdata)
        else:  # 左边数
            if self.leftdata == "":
                self.leftdata = "0."
            else:
                self.leftdata += "."
            self.ui.lineEdit_rst.setText(self.leftdata)

    def clicked_clear(self):  # 清零
        self.initdata()
        self.ui.lineEdit_rst.setText("0")  # 结果栏里默认为 0

    def clicked_num(self):
        sender = self.sender()  # sender 是发射信号的按钮

        if self.bcalculated == True:  # 右边数
            if (self.rightdata == "0" or self.rightdata == "") and sender.text() == "0":
                self.ui.lineEdit_rst.setText("0")
            else:
                self.rightdata += sender.text()  # 右边数字
                self.ui.lineEdit_rst.setText(self.rightdata)
        else:  # 左边数
            if self.ui.lineEdit_rst.text() == "0" and sender.text() == "0":
                self.ui.lineEdit_rst.setText("0")
            else:
                self.leftdata += sender.text()   # 左边数字
                self.ui.lineEdit_rst.setText(self.leftdata)

    def clicked_result(self):  # 点击等号
        if self.error:  # 除数为0
            self.initdata()
            self.error = True
            self.ui.lineEdit_rst.setText("除数不能为0,请归零后重新开始")
        else:
            self.ui.lineEdit_rst.setText(str(self.getresult()))

    def getresult(self):  # 计算结果
        # 把空值转为 "0"
        self.leftdata = self.leftdata if self.leftdata != "" else "0"
        self.rightdata = self.rightdata if self.rightdata != "" else "0"

        try:
            self.leftdata = Decimal(self.leftdata)
            self.rightdata = Decimal(self.rightdata)
        except:
            return self.leftdata

        if self.operator == "+":
            self.leftdata += self.rightdata  # 左数据为运算结果
        elif self.operator == "-":
            self.leftdata -= self.rightdata
        elif self.operator == "×":
            self.leftdata *= self.rightdata
        elif self.operator == "^":
            self.leftdata = pow(self.leftdata, self.rightdata)
        elif self.operator == "÷":
            if self.rightdata == 0:
                self.initdata()
                self.error = True
                return
            self.leftdata /= self.rightdata

        self.rightdata = ""
        self.leftdata = str(self.leftdata)
        return self.leftdata

    def clicked_calculate(self):
        if self.bcalculated == True:  # 点击过运算和被运算的数字了
            rst = str(self.getresult())
            if self.error:  # 除数为0
                self.ui.lineEdit_rst.setText("除数不能为0,请归零后重新开始")
            else:
                self.ui.lineEdit_rst.setText(rst)

        sender = self.sender()  # sender 是发射信号的按钮
        self.operator = sender.text()
        self.bcalculated = True

app = QApplication(sys.argv)
mycal = MyWidget()
mycal.show()
app.exec_()


如果以上内容对您有帮助,请老板用微信扫一下赞赏码,赞赏后加微信号 birdpython 领取免费视频。


登录后评论

user_image
Milo-Yip
2020年11月23日 19:52 回复

谢谢老师,学习了~~


user_image
MagiLu
2020年10月23日 13:31 回复

正好毕业设计是这个项目,拿走不谢哈哈


user_image
tombkeeper
2020年8月23日 08:10 回复

不错,不错


user_image
邪叫教主
2020年3月23日 22:41 回复

打卡学习,Qt 很强大,等会我做个音乐播放器