一個基於python3+PyQt5實現的簡單計算器程式
阿新 • • 發佈:2019-01-03
【開發平臺】ubuntu14 + python3 + PyQt5
【執行介面】
【原始碼】
# -*- coding: utf-8 -*- ''' Description: A simple calculater based on PyQt5 Author: waterfronter Last Edit: 2017.10.15 ''' import sys import re from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QGridLayout, QGroupBox, QLineEdit from PyQt5.QtCore import Qt class Calculater(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setWindowTitle('Calculater') self.setGeometry(100, 100, 350, 150) #禁用最大化按鈕 self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint) #顯示區 self.resultflag = 0 self.errflag = 0 self.display = QLineEdit('0') self.display.setReadOnly(True) self.display.setAlignment(Qt.AlignRight) self.display.setMaxLength(30) #操作區 self.createGridLayout() windowLayout = QVBoxLayout() windowLayout.addWidget(self.display) windowLayout.addWidget(self.horizontalGroupBox) self.setLayout(windowLayout) self.show() def createGridLayout(self): self.horizontalGroupBox = QGroupBox('') layout = QGridLayout() #操作區第1行 button00 = QPushButton('Backspace') button00.clicked.connect(self.on_click) layout.addWidget(button00, 0, 0) button01 = QPushButton('Clear') button01.clicked.connect(self.on_click) layout.addWidget(button01, 0, 1) button02 = QPushButton('Clear All') button02.clicked.connect(self.on_click) layout.addWidget(button02, 0, 2) button03 = QPushButton('/') button03.clicked.connect(self.on_click) layout.addWidget(button03, 0, 3) #操作區第2行 button10 = QPushButton('7') button10.clicked.connect(self.on_click) layout.addWidget(button10, 1, 0) button11 = QPushButton('8') button11.clicked.connect(self.on_click) layout.addWidget(button11, 1, 1) button12 = QPushButton('9') button12.clicked.connect(self.on_click) layout.addWidget(button12, 1, 2) button13 = QPushButton('*') button13.clicked.connect(self.on_click) layout.addWidget(button13, 1, 3) #操作區第3行 button20 = QPushButton('4') button20.clicked.connect(self.on_click) layout.addWidget(button20, 2, 0) button21 = QPushButton('5') button21.clicked.connect(self.on_click) layout.addWidget(button21, 2, 1) button22 = QPushButton('6') button22.clicked.connect(self.on_click) layout.addWidget(button22, 2, 2) button23 = QPushButton('-') button23.clicked.connect(self.on_click) layout.addWidget(button23, 2, 3) #操作區第4行 button30 = QPushButton('1') button30.clicked.connect(self.on_click) layout.addWidget(button30, 3, 0) button31 = QPushButton('2') button31.clicked.connect(self.on_click) layout.addWidget(button31, 3, 1) button32 = QPushButton('3') button32.clicked.connect(self.on_click) layout.addWidget(button32, 3, 2) button33 = QPushButton('+') button33.clicked.connect(self.on_click) layout.addWidget(button33, 3, 3) #操作區第5行,其中'0'獨佔1行2列 button40 = QPushButton('0') button40.clicked.connect(self.on_click) layout.addWidget(button40, 4, 0, 1, 2) #從4行0列開始佔1行2列 button42 = QPushButton('.') button42.clicked.connect(self.on_click) layout.addWidget(button42, 4, 2, 1, 1) #從4行2列開始佔1行1列 button43 = QPushButton('=') button43.clicked.connect(self.on_click) layout.addWidget(button43, 4, 3, 1, 1) #從4行3列開始佔1行1列 self.horizontalGroupBox.setLayout(layout) def on_click(self): source = self.sender() #全部輸入清零 if source.text() == 'Clear All': self.display.setText('0') #刪除最近輸入的一個運算元 elif source.text() == 'Clear': if self.resultflag != 1: clrreg = re.compile(r'[0-9.]+$') substr = clrreg.sub('', self.display.text()) if substr == '': substr = '0' self.display.setText(substr) #退格鍵功能 elif source.text() == 'Backspace': if self.resultflag != 1: if len(self.display.text()) <= 1: newtext = '0' else: newtext = self.display.text()[0 : (len(self.display.text()) - 1)] self.display.setText(newtext) #計算輸入的算術表示式並將結果顯示 elif source.text() == '=': if self.resultflag != 1: try: disstr = self.display.text()[:] #考慮表示式不完整的情況處理:尾部為運算子*/則補1 if disstr[len(disstr) - 1 : ] in '*/': calstr = disstr + '1' #尾部為運算子+-或小數點則補0 elif disstr[len(disstr) - 1 : ] in '+-.': calstr = disstr + '0' else: calstr = disstr[:] result = str(eval(calstr)) #考慮除0異常處理 except (ZeroDivisionError, Exception) as errinfo: result = 'Error: '+ str(errinfo) self.errflag = 1 self.display.setText(result) self.resultflag = 1 #輸入數字或小數點:將算術表示式輸入同步顯示出來 else: self.numhandle() def numhandle(self): rawstr = self.display.text()[:] strlen = len(rawstr) lastchar = rawstr[strlen-1 : ] inchar = self.sender().text()[:] newstr = '' #前面輸入尚未計算結果 if self.resultflag != 1: #當前最後一個字元為運算子(+-*/) if lastchar in '+-*/': #輸入為0-9 -> 直接追加 if inchar in '0123456789': newstr = rawstr + inchar #輸入為運算子 -> 忽略輸入 elif inchar in '+-*/': newstr = rawstr[:] #輸入為小數點 -> 小數點前補0再追加 else: newstr = rawstr + '0' + inchar #當前最後一個字元為小數點 elif lastchar == '.': #輸入為0-9 -> 直接追加 if inchar in '0123456789': newstr = rawstr + inchar #輸入為小數點 -> 忽略輸入 elif inchar == '.': newstr = rawstr[:] #輸入為運算子 -> 運算子前補0再追加 else: newstr = rawstr + '0' + inchar #當前最後一個字元為0-9 else: numreg1 = re.compile(r'[+\-*/]{0,1}[0-9]+\.[0-9]*[0-9]$') srchrslt1 = numreg1.search(rawstr) #當前最後一個數字前面已經有小數點 if srchrslt1 != None: #輸入為小數點 -> 忽略輸入 if inchar == '.': newstr = rawstr[:] #輸入為0-9或運算子 -> 直接追加 else: newstr = rawstr + inchar #當前最後一個數字前面沒有小數點 else: numreg2 = re.compile(r'[+\-*/]0$') srchrslt2 = numreg2.search(rawstr) #當前最後一個字元為0且作為最近運算子後的第一個數字 if srchrslt2 != None: #輸入為小數點或運算子 -> 直接追加 if inchar == '.' or inchar in '+-*/': newstr = rawstr + inchar #輸入為0-9 -> 忽略輸入 else: newstr = rawstr[:] #當前字串即是'0' elif rawstr == '0': #輸入為0-9 -> 用輸入取代原字元'0' if inchar in '0123456789': newstr = inchar[:] #輸入為小數點或運算子 -> 直接追加 else: newstr = rawstr + inchar #其他情況均可直接追加 else: newstr = rawstr + inchar #前面輸入已經計算出結果 else: #考慮計算有無異常 if self.errflag == 0: #輸入為運算子 -> 直接追加 if inchar in '+-*/': newstr = rawstr + inchar #輸入小數點 -> 以小數點前補0重新整理顯示 elif inchar == '.': newstr = '0' + inchar #輸入0-9 -> 以輸入重新整理顯示 else: newstr = inchar[:] else: #輸入為運算子 -> 忽略輸入並擦除err資訊 if inchar in '+-*/': newstr = '0' #輸入小數點 -> 以小數點前補0重新整理顯示 elif inchar == '.': newstr = '0' + inchar #輸入0-9 -> 以輸入重新整理顯示 else: newstr = inchar[:] self.errflag = 0 self.resultflag = 0 self.display.setText(newstr) if __name__ == '__main__': app = QApplication(sys.argv) ex = Calculater() sys.exit(app.exec_())