基于PYQT的简易计算器
本人目前是一名在校大学生,正在学习Python,接触到了PYQT,利用所学的PYQT知识制作了一个简易计算器,实现了win10自带计算器的部分功能,并可以进行进制转换。限本人能力有限,所以本文章会与诸多不合理或不专业之处,请谅解。
一、引言
本项目通过使用QTdesinger来进行界面搭建,可以通过鼠标或者键盘进行数据输入和删除,基本实现简单的计算器功能,并且可以实现进制转换的功能。
开发环境:Visual Studio Code
操作系统:Windows10
Python版本:3.9.1
二、QTdesinger界面
在qt界面中,使用了QLabel、QLineEdit、QPushButton与QCheckBox四种插件,同时使用了Vertical Layout(水平布局) 、Horizontal Layout(垂直布局)与Grid Layout (栅格布局)三种布局方式。
按键颜色、窗口颜色、字体类型与字体大小通过右侧属性编辑器中的styleSheet选项进行更改,使用时选择所要更改的对象,点击...进行更改。
注意,点击添加颜色时要选择background-color(背景颜色)进行更改,若有些选项下直接点击添加颜色可能会报错(左下角显示无效样式表)。
三、UI文件编译成Python后部分代码
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "简易计算器"))
self.label_2.setText(_translate("MainWindow", "简易计算器"))
self.label_3.setText(_translate("MainWindow", "输入:"))
self.label_4.setText(_translate("MainWindow", "结果:"))
self.but7.setText(_translate("MainWindow", "7"))
self.pushButton.setText(_translate("MainWindow", "退格"))
self.butMul.setText(_translate("MainWindow", "*"))
self.but4.setText(_translate("MainWindow", "4"))
self.butclar.setText(_translate("MainWindow", "清除"))
self.butMul_3.setText(_translate("MainWindow", "e"))
self.butMul_2.setText(_translate("MainWindow", "π"))
self.butDot.setText(_translate("MainWindow", "."))
self.but6.setText(_translate("MainWindow", "6"))
self.but0.setText(_translate("MainWindow", "0"))
self.but5.setText(_translate("MainWindow", "5"))
self.butSub.setText(_translate("MainWindow", "-"))
self.but9.setText(_translate("MainWindow", "9"))
self.but00.setText(_translate("MainWindow", "00"))
self.butAdd.setText(_translate("MainWindow", "+"))
self.but2.setText(_translate("MainWindow", "2"))
self.butAdd_3.setText(_translate("MainWindow", ")"))
self.but3.setText(_translate("MainWindow", "3"))
self.but1.setText(_translate("MainWindow", "1"))
self.butDiv.setText(_translate("MainWindow", "/"))
self.but8.setText(_translate("MainWindow", "8"))
self.butClr.setText(_translate("MainWindow", "C"))
self.butEqr.setText(_translate("MainWindow", "="))
self.butAdd_2.setText(_translate("MainWindow", "("))
self.label.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:18pt; font-weight:600;\">进制转换:</span></p></body></html>"))
self.butBin.setText(_translate("MainWindow", "二进制"))
self.checkBox.setText(_translate("MainWindow", "二进制直接输入"))
self.butOct.setText(_translate("MainWindow", "八进制"))
self.checkBox1.setText(_translate("MainWindow", "八进制直接输入"))
self.butHex.setText(_translate("MainWindow", "十六进制"))
self.checkBox2.setText(_translate("MainWindow", "十六进制直接输入"))
四、主程序代码
请注意,在主程序代码编写时,出去基本的MainWindow窗口之外,其它方法实现过程中本人未用面向对象的方式编写,只使用面向过程方式编写,因此代码可能比较冗杂。(注意UI文件的命名必须为MainW)
1.主窗体设置代码
# 系统包
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget
# 项目包
from Ui_MainWindow import Ui_MainWindow
from math import *
from PyQt5.QtCore import *
# 主窗体设置
self.show() #窗口显示
if __name__ == '__main__': #窗口驱动
app = QtWidgets.QApplication(sys.argv)
MainWindow = CMainWindow()
sys.exit(app.exec_())
2.数字按键输入代码
def Push1(self): #数字1输入
c = self.checkBox.isChecked() #c、d、e分别代表二、八、十六进制
d = self.checkBox1.isChecked()# 当所对应选项卡勾选时,返回True
e = self.checkBox2.isChecked()#未勾选时,返回False
if c == True: #二进制勾选时,将1写入二进制对应的文本框中
self.txtBin.insert("1")
if d == True: #二进制勾选时,将1写入八进制对应的文本框中
self.txtOct.insert("1")
if e == True: #二进制勾选时,将1写入十六进制对应的文本框中
self.txtHex.insert("1")
if c == False and d == False and e == False:#都未勾选时
self.txtDisplay.insert("1") #将数字写入到计算文本框中
这里只展示数字一的按键输入,其它数字的按键输入与此类似。
解析:因为使用的QCheckBox控件,勾选时返回True,未勾选时返回False,所以我们在这里可以通过勾没勾选来选择将数据输入到那个文本框中。
3.数字键盘输入代码
def keyPressEvent(self, event):
if (event.key() == Qt.Key_1): #当键盘1按键按下时
c = self.checkBox.isChecked()
d = self.checkBox1.isChecked()
e = self.checkBox2.isChecked()
if c == True:
self.txtBin.insert("1")
if d == True:
self.txtOct.insert("1")
if e == True:
self.txtHex.insert("1")
if c == False and d == False and e == False:
self.txtDisplay.insert("1")
这里只展示数字一的键盘输入,其它数字的输入与此类似。
相较于数字按键输入,这里之多了两行代码,其余部分与数字按键输入相同
def keyPressEvent(self, event):
if (event.key() == Qt.Key_1):#当键盘1按下时
在这里定义一个键盘输入方法,当event事件返回的数值等于键盘1的数值时,执行。若不知道怎么表示按键( Qt.Key_1),则可以换成键盘对应代码,如 event.key() == 52 (同等于event.key() == Qt.Key_4)。在这里我会列出一部分按键代码,供大家参考。
1 | 2 | 3 | 4 | 5 | 6 | 7 |
49 | 50 | 51 | 52 | 53 | 54 | 55 |
8 | 9 | 0 | + | - | * | / |
56 | 57 | 48 | 45 | 45 | 42 | 47 |
4.按键清除代码
def Pushclar(self): #清除
c = self.checkBox.isChecked()
d = self.checkBox1.isChecked()
e = self.checkBox2.isChecked()
if c == True:
self.txtBin.clear()
if d == True:
self.txtOct.clear()
if e == True:
self.txtHex.clear()
if c == False and d == False and e == False:
self.txtNumber.clear()
self.txtOct.clear()
self.txtBin.clear()
self.txtHex.clear()
逻辑判断大体与上面相同,使用self.文本名.clear()对指定文本进行清除,这里我们不过多赘述。但要注意,上述的写法当对应进制被勾选时,清除勾选进制的文本,若都未勾选,则清除计算结果和所有进制文本。
5.运算代码
def calculate(self):
c = self.checkBox.isChecked()
d = self.checkBox1.isChecked()
e = self.checkBox2.isChecked()
text = self.txtDisplay.text()
if c == False and d == False and e == False:
try:
self.txtNumber.setText(str(eval(text)))
#self.txtDisplay.setText(str(eval(text)))
#eval() 函数用来执行一个字符串表达式,并返回表达式的值。
except:
self.txtNumber.setText('错误')
在这里我们使用了一个函数 eval,eval() 函数用来执行一个字符串表达式,并返回表达式的值,来对数字进行运算。这里我们读取了运算文本框中的字符,通过eval函数对齐进行运算,得出结果。使用try是为了防止为输入内容时进行运算或者输入错误的内容进行运算时发生的报错(例如:()*5),并给予提示。
6.进制转换代码
def PushHex(self):
c = self.checkBox.isChecked()
d = self.checkBox1.isChecked()
e = self.checkBox2.isChecked()
if e == True:
try:
e = float(self.txtHex.text())
f = int(round(e,0))
i = hex(f)
self.txtHex.setText(str(i))
except:
self.txtNumber.setText("数据有误,请重新输入")
elif c == False and d == False and e == False:
try:
e = float(self.txtNumber.text())
f = int(round(e,0))
i = hex(f)
self.txtHex.setText(str(i))
except:
self.txtNumber.setText("数据有误,请重新输入")
我们以十六进制举例,二进制与八进制同理。
c、d、e还是读取是否勾选,若十六进制被勾选时,代码执行的是读取十六进制文本中的数据,先转换为float类型,之后通过round函数进行四舍五入,在转换为int类型,最后利用Hex函数进行进制的转换,在输出到十六进制文本框中。若十六进制未被勾选,则读取计算结果文本框中数据容,先转换为float类型,之后通过round函数进行四舍五入,在转换为int类型,最后利用Hex函数进行进制的转换,输出到十六进制文本框中。比较啰嗦,但是较好理解与实现。
7.按键与键盘退格代码
def backspace(self): #按键退格
c = self.checkBox.isChecked()
d = self.checkBox1.isChecked()
e = self.checkBox2.isChecked()
if c == True:
self.txtBin.backspace()
if d == True:
self.txtOct.backspace()
if e == True:
self.txtHex.backspace()
if c == False and d == False and e == False:
self.txtDisplay.backspace()
def keyPressEvent(self, event):
if (event.key() == 16777219): #按键按下退格时
c = self.checkBox.isChecked()
d = self.checkBox1.isChecked()
e = self.checkBox2.isChecked()
if c == True:
self.txtBin.backspace()
if d == True:
self.txtOct.backspace()
if e == True:
self.txtHex.backspace()
if c == False and d == False and e == False:
self.txtDisplay.backspace()
按键退格与键盘退格也是类似。都是先读取选中的那个文本,在进行相应的退格。但是退格不能再输出文本框应用。
8.完整代码
https://github.com/AuxPnW/-.git
五、程序打包
在程序打包时,我们使用auto-py-to-exe这个插件。
首先打开cmd(命令提示符),输入pip install auto-py-to-exe,回车,等待安装完毕。
安装完毕后,接着输入Auto-py-to-exe,回车。
之后会弹出这个界面。点击浏览,选择你要打包的Python文件,若需要控制台则选择基于控制台,若不需要则选择基于窗口的。我们可以根据需要添加图标等等。
打包完之后点击打开输出目录,你的Python文件会生成一个文件夹,点击exe文件,直接可以运行。