不识有话说
好久不见,甚是想念,
因为最近都在忙着学习,
所以好久没有写博客了,
这几天刚好在学pyqt5,
所以就想着先写一个计算器练练手。
项目展示
我觉得害不错,除了颜色有点丑之外(对不起,我真不会配色)
除了有一丝丝的瑕疵,该有的功能都有哦
项目准备
import sys
import math
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QGridLayout, QLabel
需要安装的模块
sys,math,PyQt5
安装方法
pip/pip3 install 模块名
项目讲解
第一步当然是先创建一个窗口啦
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QWidget, QApplication
class MyWindow(QWidget):
def __init__(self):
# 切记一定要调用父类的__init__方法,因为它里面有很多对UI空间的初始化操作
super().__init__()
# 额外设置一个init_ui函数是防止__init__方法过于臃肿
self.init_ui()
def init_ui(self):
# 设置窗口标题
self.setWindowTitle("计算器")
# 设置窗口图标
self.setWindowIcon(QIcon('笑脸.png'))
# 设置一个固定的窗口大小
self.setFixedSize(328, 400)
# 设置背景颜色
self.setStyleSheet('background-color: white;')
if __name__ == '__main__':
# 只要是qt制作的App,必须有且只有一个QApplication对象
# sys.argv当做参数将运行时的命令参数传递给QApplication对象
app = QApplication(sys.argv)
# 创建窗口对象
w = MyWindow()
# 展示窗口
w.show()
# 程序进行循环等待状态
app.exec()
这样我们的小框框就做出来啦
第二步就让我们把显示计算过程和结果的框框展示出来吧
def init_ui(self):
self.setWindowTitle("计算器")
self.setWindowIcon(QIcon('笑脸.png'))
self.setFixedSize(328, 400)
self.setStyleSheet('background-color: white;')
# 整体垂直布局
layout = QVBoxLayout()
# 显示计算过程的文本框
self.text_count = QLabel('')
# 设置计算过程框的字体为黑体
self.text_count.setStyleSheet('font-family: SimHei;')
# 把计算过程框添加进垂直布局容器中
layout.addWidget(self.text_count)
# 显示结果的文本框
self.text_reult = QLabel('0')
# 将该文本框的内容显示设置为右对齐
self.text_reult.setAlignment(Qt.AlignRight)
# 设置结果框的字号为25像素,字体为黑体
self.text_reult.setStyleSheet('font-size: 25px;font-family: SimHei;')
# 把输入框添加到容器中
layout.addWidget(self.text_reult)
# 把垂直布局容器添加到主界面,用于显示内容
self.setLayout(layout)
写完是这样的,是不是有点奇怪为什么0在这么奇怪的位置
当我们给文本框加上背景颜色
发现原来是因为这俩个文本框把所有位置都霸占了,
所以我们的小0才会无辜的待在右侧的中间,可怜可悲可叹。
至于为什么会这样,是因为我们的
垂直布局容器在没有其他容器或控件抢占空间的情况下,
默认把所有领土收归国有,
然后作为垂直布局国仅有的俩位文本框先生,
当然是一人一半啦。
self.text_count.setStyleSheet('font-family: SimHei;background-color: red;')
self.text_reult.setStyleSheet('font-size: 25px;font-family: SimHei;background-color: red;')
第三步我们来把重要的计算按钮加上
def init_ui(self):
self.setWindowTitle("计算器")
self.setWindowIcon(QIcon('笑脸.png'))
self.setFixedSize(328, 400)
self.setStyleSheet('background-color: white;')
layout = QVBoxLayout()
self.text_count = QLabel('')
self.text_count.setStyleSheet('font-family: SimHei;')
layout.addWidget(self.text_count)
self.text_reult = QLabel('0')
self.text_reult.setAlignment(Qt.AlignRight)
self.text_reult.setStyleSheet('font-size: 25px;font-family: SimHei;')
layout.addWidget(self.text_reult)
# 准备按钮数据
data = {
0: ['%', 'CE', 'C', '<-'],
1: ['1/x', 'x^2', '2√x', '÷'],
2: ['7', '8', '9', '×'],
3: ['4', '5', '6', '-'],
4: ['1', '2', '3', '+'],
5: ['±', '0', '.', '='],
}
# 网格布局
grid = QGridLayout()
# 此时line_number是第几行,line_data是当前行的数据
for line_number, line_data in data.items():
# 此时col_number是第几列,number是要显示的符号
for col_number, number in enumerate(line_data):
self.btn = QPushButton(number)
# 判断按钮number值并分别设置样式
if number == '=':
self.btn.setStyleSheet('''
width: 80px;
height: 40px;
background-color: red;
font-family: SimHei;
''')
elif number.isdigit() or number == '±' or number == '.':
self.btn.setStyleSheet('''
width: 80px;
height: 40px;
background-color: #f0c9cf;
font-family: SimHei;
''')
else:
self.btn.setStyleSheet('''
width: 80px;
height: 40px;
background-color: #63bbd0;
font-family: SimHei;
''')
# 按钮被点击后(发送信号)调用Result函数(槽函数)
# self.btn.clicked.connect(self.Result) # 最一步才能用上,用于点击事件
# 将创建的按钮添加进网格布局容器中
grid.addWidget(self.btn, line_number, col_number)
# 把网格布局追加到垂直布局容器中
layout.addLayout(grid)
self.setLayout(layout)
现在我们已经有其形了,有一说一,看久了害觉得挺好看的
第四步也是我们的最后一步,添加点击事件使其能正常使用
(可以把上一步self.btn.clicked.connect(self.Result)封印解除了)
这一步其实应该是最简单的一步了,
毕竟数学计算应该有一点python基础的都会写
唯一的(我的)卡点可能就是self.sender().text(),
我一开始不知道这方法,
完全不知道怎么判断和获取按钮里的值,
无奈疯狂百度,
得此良法(kkz)
class MyWindow(QWidget):
def __init__(self):...
def init_ui(self):...
def Result(self):
# 获取当前点击按钮的值
text = self.sender().text()
if text.isdigit() or text == '.' or text in '+-×÷':
self.num += text
self.text_count.setText(self.num)
elif text == '=':
if '×' in self.num:
self.num = self.num.replace('×', '*')
elif '÷' in self.num:
self.num = self.num.replace('÷', '/')
self.text_reult.setText(str(eval(self.num)))
self.num = str(eval(self.num))
elif text == 'C':
self.num = ''
self.text_count.setText(self.num)
self.text_reult.setText('0')
elif text == '<-':
self.num = self.num[:-1]
self.text_count.setText(self.num)
elif text == 'x^2':
self.text_reult.setText(str(eval(self.num) * eval(self.num)))
self.num = str(eval(self.num) * eval(self.num))
elif text == '%':
self.text_reult.setText(str(eval(self.num) / 100))
self.num = str(eval(self.num) / 100)
elif text == '1/x':
self.text_reult.setText(str(1 / eval(self.num)))
self.num = str(1 / eval(self.num))
elif text == '2√x':
self.text_reult.setText(str(math.sqrt(eval(self.num))))
self.num = str(math.sqrt(eval(self.num)))
elif text == '±':
self.text_reult.setText(str(-eval(self.num)))
self.num = str(-eval(self.num))
讲完啦,如果觉得有用的话,
希望可以一键三连(点赞,收藏,关注)资瓷一下俺这个萌新
完整代码
import sys
import math
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QGridLayout, QLabel
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
self.num = ''
def init_ui(self):
self.setWindowTitle("计算器")
self.setWindowIcon(QIcon('笑脸.png'))
self.setFixedSize(328, 400)
self.setStyleSheet('background-color: white;')
data = {
0: ['%', 'CE', 'C', '<-'],
1: ['1/x', 'x^2', '2√x', '÷'],
2: ['7', '8', '9', '×'],
3: ['4', '5', '6', '-'],
4: ['1', '2', '3', '+'],
5: ['±', '0', '.', '='],
}
layout = QVBoxLayout()
self.text_count = QLabel('')
self.text_count.setStyleSheet('font-family: SimHei;')
layout.addWidget(self.text_count)
self.text_reult = QLabel('0')
self.text_reult.setAlignment(Qt.AlignRight)
self.text_reult.setStyleSheet('font-size: 25px;font-family: SimHei;')
layout.addWidget(self.text_reult)
grid = QGridLayout()
for line_number, line_data in data.items():
for col_number, number in enumerate(line_data):
self.btn = QPushButton(number)
if number == '=':
self.btn.setStyleSheet('''
width: 80px;
height: 40px;
background-color: red;
font-family: SimHei;
''')
elif number.isdigit() or number == '±' or number == '.':
self.btn.setStyleSheet('''
width: 80px;
height: 40px;
background-color: #f0c9cf;
font-family: SimHei;
''')
else:
self.btn.setStyleSheet('''
width: 80px;
height: 40px;
background-color: #63bbd0;
font-family: SimHei;
''')
self.btn.clicked.connect(self.Result)
grid.addWidget(self.btn, line_number, col_number)
layout.addLayout(grid)
self.setLayout(layout)
def Result(self):
text = self.sender().text()
if text.isdigit() or text == '.' or text in '+-×÷':
self.num += text
self.text_count.setText(self.num)
elif text == '=':
if '×' in self.num:
self.num = self.num.replace('×', '*')
elif '÷' in self.num:
self.num = self.num.replace('÷', '/')
self.text_reult.setText(str(eval(self.num)))
self.num = str(eval(self.num))
elif text == 'C':
self.num = ''
self.text_count.setText(self.num)
self.text_reult.setText('0')
elif text == '<-':
self.num = self.num[:-1]
self.text_count.setText(self.num)
elif text == 'x^2':
self.text_reult.setText(str(eval(self.num) * eval(self.num)))
self.num = str(eval(self.num) * eval(self.num))
elif text == '%':
self.text_reult.setText(str(eval(self.num) / 100))
self.num = str(eval(self.num) / 100)
elif text == '1/x':
self.text_reult.setText(str(1 / eval(self.num)))
self.num = str(1 / eval(self.num))
elif text == '2√x':
self.text_reult.setText(str(math.sqrt(eval(self.num))))
self.num = str(math.sqrt(eval(self.num)))
elif text == '±':
self.text_reult.setText(str(-eval(self.num)))
self.num = str(-eval(self.num))
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec()
打包方法
安装PyInstaller包
pip/pip3 install PyInstaller
打包方法
pyinstaller -F -w [-i icon相对于入口文件的路径]代码名.py
打包后的exe文件在当前目录的dist文件夹下