主窗口 信号和槽 对输入格式的判断 启动程序
主窗口以及信号和槽: calculator_window.py
程序启动: main.py
关键点:6个自定义槽函数的编写,包含了对输入运算符的判断
main.py
from calculator_window import CalculatorWindow
from PyQt5.QtWidgets import QApplication
import sys
if __name__ == '__main__':
# application 对象
app = QApplication(sys.argv)
calculator = CalculatorWindow()
sys.exit(app.exec_())
calculator_window.py
from PyQt5 import QtWidgets
from PyQt5.QtGui import QIcon, QColor
import ctypes
from calculator import Ui_YinYueCalculator
from transfer import transfer
from postfix_evaluation import postfix_evaluation
class CalculatorWindow(QtWidgets.QMainWindow, Ui_YinYueCalculator):
# static变量
original_expression = "" # 存放需要计算的原始表达式
history_expression = "" # 存放历史记录表达式及结果
dot_num = 0 # 记录有几个小数点
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowTitle('YinYueCalculator') # 设置窗口标题
self.setWindowIcon(QIcon('1.jpg')) # 设置窗口图标
self.setStyleSheet('QWidget{background-color:%s}' % QColor(222, 222, 222).name()) # 设置窗口背景色
self.setWindowOpacity(0.85) # 设置整个计算器窗口的透明度
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid") # 任务栏图标
self.show()
# 将信号连接上槽函数
# 操作数按钮的连接
self.num0.clicked.connect(self.digit_operation_pressed)
self.num1.clicked.connect(self.digit_operation_pressed)
self.num2.clicked.connect(self.digit_operation_pressed)
self.num3.clicked.connect(self.digit_operation_pressed)
self.num4.clicked.connect(self.digit_operation_pressed)
self.num5.clicked.connect(self.digit_operation_pressed)
self.num6.clicked.connect(self.digit_operation_pressed)
self.num7.clicked.connect(self.digit_operation_pressed)
self.num8.clicked.connect(self.digit_operation_pressed)
self.num9.clicked.connect(self.digit_operation_pressed)
# 运算符按钮的连接
self.plus.clicked.connect(self.digit_operation_pressed)
self.minus.clicked.connect(self.digit_operation_pressed)
self.multiply.clicked.connect(self.digit_operation_pressed)
self.devide.clicked.connect(self.digit_operation_pressed)
self.leftbracket.clicked.connect(self.digit_operation_pressed)
self.rightbracket.clicked.connect(self.digit_operation_pressed)
self.dot.clicked.connect(self.digit_operation_pressed)
# 等于号按钮的连接
self.equal.clicked.connect(self.equal_pressed)
# 清空符号C按钮的连接
self.c.clicked.connect(self.clear_all_pressed)
# 历史记录history按钮的连接
self.history.clicked.connect(self.show_history)
# backspace按钮的连接
self.backspace.clicked.connect(self.backspace_pressed)
# 操作数和运算符的槽函数
def digit_operation_pressed(self):
self.any_pressed() # 调用全局槽函数
button = self.sender()
# 开头不允许是"+×÷)."
if self.original_expression == "" and button.text() in "+×÷).":
pass
else:
self.output.setText(self.output.text() + button.text()) # 设置显示文字
self.original_expression = self.output.text() # 加入原始表达式
if button.text() == ".":
self.dot_num = self.dot_num + 1 # 小数点个数加一
if button.text() in "+-×÷()":
self.dot_num = 0 # 小数点个数清零
# "."不允许跟在运算符和"."之后
if button.text() in "." and self.original_expression[-2] in "+-×÷().":
self.original_expression = self.original_expression[:-1] # 从原始表达式中移除最后一个
self.output.setText(self.original_expression)
# "+×÷)"不能跟在"+×÷("之后
elif button.text() in "+×÷)" and self.original_expression[-2] in "+×÷(.":
self.original_expression = self.original_expression[:-2] + button.text() # 当前运算符替换上一个
self.output.setText(self.original_expression)
# "("不能跟在")."之后
elif len(self.original_expression) > 1 and button.text() in "(" and self.original_expression[-2] in ").":
self.original_expression = self.original_expression[:-1] # 从原始表达式中移除最后一个
self.output.setText(self.original_expression)
# 小数点个数大于一时删除最后一个小数点
elif button.text() == "." and self.dot_num > 1:
self.original_expression = self.original_expression[:-1] # 从原始表达式中移除"."
self.output.setText(self.original_expression)
self.dot_num = self.dot_num - 1
# 等于号获取最终结果的槽函数
def equal_pressed(self):
if self.original_expression[-1] in "+-×÷.(" or self.original_expression == "" or self.output.text() == "":
pass
else:
button = self.sender()
self.output.setText(self.output.text() + button.text())
infix = self.original_expression # 将原始表达式赋值给infix
postfix, operand = transfer(infix) # 中缀表达式infix作为实参传递给transfer函数获取后缀表达式postfix和对应字典
final_result = postfix_evaluation(postfix, operand) # 调用postfix_evaluation函数获取最终计算结果
result = str("%.2f" % final_result) # 将结果保留两位小数
self.output.setText(result)
self.history_expression = self.original_expression + button.text() + result # 将表达式和结果放进历史记录
self.original_expression = "" # 原始表达式清空
self.dot_num = 0
# C清空的槽函数
def clear_all_pressed(self):
self.output.setText("")
self.original_expression = ""
self.dot_num = 0
# 历史记录槽函数
def show_history(self):
if self.history_expression == "":
self.output.setText("NO HISTORY")
else:
self.output.setText(self.history_expression)
# backspace槽函数
def backspace_pressed(self):
if self.original_expression == "" and self.output.text() != "":
self.output.setText("")
self.dot_num = 0
elif self.original_expression[-1] == ".":
self.dot_num = self.dot_num - 1
self.original_expression = self.original_expression[:-1] # 删除原始表达式最后一个
self.output.setText(self.original_expression)
else:
self.original_expression = self.original_expression[:-1] # 删除原始表达式最后一个
self.output.setText(self.original_expression)
# 全局槽函数
def any_pressed(self):
# 原始表达式为空,但显示框有值(表明显示框中是历史记录或"NO HISTORY")
if self.original_expression == "" and self.output.text != "":
self.output.setText("")
——2020/12/5(殷越)