使用PyQt5制作计算器(一)
在之前的博客中,介绍了PyQt5环境搭建((131条消息) PyQt5环境搭建_jgw2008的专栏-CSDN博客)
目录
在之前的博客中,介绍了 PyQt5环境搭建,今天使用PyQt5制作一个简单的计算器。
下面开始正文。
一. 使用designer.exe设计UI
打开designer.exe, 选择 “文件(F)” -> "新建(N)", 选择模板“Widget”然后点击创建。
UI中使用了QLineEdit、QGridLayout和QPushButton,其中button是放在GridLayout中摆放,详细设计如下图;设计完成后,保存为“CalUi.ui”文件。
二. 使用pyuic5.exe将ui文件转为py文件
使用如下命令将ui文件转为py文件。
pyuic5.exe -o CalUi.py CalUi.ui
转换后的CalUi.py文件如下,
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'CalUi.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# 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(600, 400)
self.lineEdit = QtWidgets.QLineEdit(Form)
self.lineEdit.setGeometry(QtCore.QRect(130, 60, 331, 40))
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.lineEdit.setFont(font)
self.lineEdit.setObjectName("lineEdit")
self.gridLayoutWidget = QtWidgets.QWidget(Form)
self.gridLayoutWidget.setGeometry(QtCore.QRect(130, 120, 326, 221))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(4, 4, 4, 4)
self.gridLayout.setHorizontalSpacing(6)
self.gridLayout.setObjectName("gridLayout")
self.btn_equal = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_equal.setFont(font)
self.btn_equal.setObjectName("btn_equal")
self.gridLayout.addWidget(self.btn_equal, 4, 2, 1, 1)
self.btn_4 = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_4.setFont(font)
self.btn_4.setObjectName("btn_4")
self.gridLayout.addWidget(self.btn_4, 2, 0, 1, 1)
self.btn_7 = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_7.setFont(font)
self.btn_7.setObjectName("btn_7")
self.gridLayout.addWidget(self.btn_7, 3, 0, 1, 1)
self.btn_1 = QtWidgets.QPushButton(self.gridLayoutWidget)
self.btn_1.setEnabled(True)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_1.setFont(font)
self.btn_1.setCheckable(False)
self.btn_1.setObjectName("btn_1")
self.gridLayout.addWidget(self.btn_1, 0, 0, 1, 1)
self.btn_9 = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_9.setFont(font)
self.btn_9.setObjectName("btn_9")
self.gridLayout.addWidget(self.btn_9, 3, 2, 1, 1)
self.btn_5 = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_5.setFont(font)
self.btn_5.setObjectName("btn_5")
self.gridLayout.addWidget(self.btn_5, 2, 1, 1, 1)
self.btn_0 = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_0.setFont(font)
self.btn_0.setObjectName("btn_0")
self.gridLayout.addWidget(self.btn_0, 4, 1, 1, 1)
self.btn_sub = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_sub.setFont(font)
self.btn_sub.setObjectName("btn_sub")
self.gridLayout.addWidget(self.btn_sub, 2, 3, 1, 1)
self.btn_8 = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_8.setFont(font)
self.btn_8.setObjectName("btn_8")
self.gridLayout.addWidget(self.btn_8, 3, 1, 1, 1)
self.btn_clear = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_clear.setFont(font)
self.btn_clear.setObjectName("btn_clear")
self.gridLayout.addWidget(self.btn_clear, 4, 0, 1, 1)
self.btn_mul = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_mul.setFont(font)
self.btn_mul.setObjectName("btn_mul")
self.gridLayout.addWidget(self.btn_mul, 3, 3, 1, 1)
self.btn_3 = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_3.setFont(font)
self.btn_3.setObjectName("btn_3")
self.gridLayout.addWidget(self.btn_3, 0, 2, 1, 1)
self.btn_div = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_div.setFont(font)
self.btn_div.setObjectName("btn_div")
self.gridLayout.addWidget(self.btn_div, 4, 3, 1, 1)
self.btn_plus = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_plus.setFont(font)
self.btn_plus.setObjectName("btn_plus")
self.gridLayout.addWidget(self.btn_plus, 0, 3, 1, 1)
self.btn_6 = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_6.setFont(font)
self.btn_6.setObjectName("btn_6")
self.gridLayout.addWidget(self.btn_6, 2, 2, 1, 1)
self.btn_2 = QtWidgets.QPushButton(self.gridLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.btn_2.setFont(font)
self.btn_2.setObjectName("btn_2")
self.gridLayout.addWidget(self.btn_2, 0, 1, 1, 1)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "计算器"))
self.btn_equal.setText(_translate("Form", "="))
self.btn_4.setText(_translate("Form", "4"))
self.btn_7.setText(_translate("Form", "7"))
self.btn_1.setText(_translate("Form", "1"))
self.btn_9.setText(_translate("Form", "9"))
self.btn_5.setText(_translate("Form", "5"))
self.btn_0.setText(_translate("Form", "0"))
self.btn_sub.setText(_translate("Form", "-"))
self.btn_8.setText(_translate("Form", "8"))
self.btn_clear.setText(_translate("Form", "清除"))
self.btn_mul.setText(_translate("Form", "*"))
self.btn_3.setText(_translate("Form", "3"))
self.btn_div.setText(_translate("Form", "/"))
self.btn_plus.setText(_translate("Form", "+"))
self.btn_6.setText(_translate("Form", "6"))
self.btn_2.setText(_translate("Form", "2"))
三. 主程序设计
1. 最小主程序设计,不响应button事件
运行下面的代码可以显示刚才做好的UI。
程序中,自定义的类“MyWindow”继承了QWidget(PyQt5中的类)和Ui_Form(刚才我们自己设计的UI的类名);在__init__函数中,呼叫了QWidget的__init__和Ui_Form的setupUi完成了初始化。
在主程序中,完成了MyWindow类的实例化和显示动作。
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow
from CalUi import Ui_Form
class MyWindow(QWidget, Ui_Form):
def __init__(self):
super(MyWindow, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())
2. 加入代码,响应button事件(由Qt的信号和槽实现)
下面是对QT的信号和槽的介绍,通俗地将,就是绑定相关的事件(比如click)和方法。使用的函数为“connect()”,比如,下面的实例中,“win.btn_clear.clicked.connect(win.btnClear_clicked)”, 就是绑定了btnClear的事件和方法。
信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。(这里提一句,Qt 的信号槽使用了额外的处理来实现,并不是 GoF 经典的观察者模式的实现方式。)
信号和槽是Qt特有的信息传输机制,是Qt设计程序的重要基础,它可以让互不干扰的对象建立一种联系。
槽的本质是类的成员函数,其参数可以是任意类型的。和普通C++成员函数几乎没有区别,它可以是虚函数;也可以被重载;可以是公有的、保护的、私有的、也可以被其他C++成员函数调用。唯一区别的是:槽可以与信号连接在一起,每当和槽连接的信号被发射的时候,就会调用这个槽。
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow
from CalUi import Ui_Form
class MyWindow(QWidget, Ui_Form):
def __init__(self):
super(MyWindow, self).__init__()
self.setupUi(self)
def btnClear_clicked(self):
self.lineEdit.clear()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.btn_clear.clicked.connect(win.btnClear_clicked)
win.show()
sys.exit(app.exec_())
3. 计算器的详细实现代码如下
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow
from CalUi import Ui_Form
class MyWindow(QWidget, Ui_Form):
def __init__(self):
super(MyWindow, self).__init__()
self.setupUi(self)
def btnClear_clicked(self):
self.lineEdit.clear()
def btn1_clicked(self):
self.lineEdit.insert("1")
def btn2_clicked(self):
self.lineEdit.insert("2")
def btn3_clicked(self):
self.lineEdit.insert("3")
def btn4_clicked(self):
self.lineEdit.insert("4")
def btn5_clicked(self):
self.lineEdit.insert("5")
def btn6_clicked(self):
self.lineEdit.insert("6")
def btn7_clicked(self):
self.lineEdit.insert("7")
def btn8_clicked(self):
self.lineEdit.insert("8")
def btn9_clicked(self):
self.lineEdit.insert("9")
def btn0_clicked(self):
self.lineEdit.insert("0")
def btnPlus_clicked(self):
self.lineEdit.insert(" + ")
def btnSub_clicked(self):
self.lineEdit.insert(" - ")
def btnMul_clicked(self):
self.lineEdit.insert(" * ")
def btnDiv_clicked(self):
self.lineEdit.insert(" / ")
def btnEqual_clicked(self):
text = self.lineEdit.text()
self.lineEdit.insert(' = %.2f' % (eval(text)))
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.btn_clear.clicked.connect(win.btnClear_clicked)
win.btn_1.clicked.connect(win.btn1_clicked)
win.btn_2.clicked.connect(win.btn2_clicked)
win.btn_3.clicked.connect(win.btn3_clicked)
win.btn_4.clicked.connect(win.btn4_clicked)
win.btn_5.clicked.connect(win.btn5_clicked)
win.btn_6.clicked.connect(win.btn6_clicked)
win.btn_7.clicked.connect(win.btn7_clicked)
win.btn_8.clicked.connect(win.btn8_clicked)
win.btn_9.clicked.connect(win.btn9_clicked)
win.btn_0.clicked.connect(win.btn0_clicked)
win.btn_plus.clicked.connect(win.btnPlus_clicked)
win.btn_sub.clicked.connect(win.btnSub_clicked)
win.btn_mul.clicked.connect(win.btnMul_clicked)
win.btn_div.clicked.connect(win.btnDiv_clicked)
win.btn_equal.clicked.connect(win.btnEqual_clicked)
win.show()
sys.exit(app.exec_())
四. 测试
运行完整代码,进行算术运行,界面如下。
五. 小结
PyQt5设计UI简单方便,功能强大,是Python中十分出色的UI库。
更多推荐
所有评论(0)