1. 기획
위에서 만들어본 간단한 계산기를 가지고 실제 사용할 수 있는 수준의 계산기를 한 번 만들어 보도록 하겠습니다.
2. 코드
from PyQt5.QtCore import Qt import sys from PyQt5.QtWidgets import * class 생선가게POS기(QWidget): def __init__(self): super().__init__() self.UI초기화() def UI초기화(self): self.s = '' ## number ## self.one = QPushButton('1') self.one.clicked.connect(lambda:self.clickedNum('1')) self.two = QPushButton('2') self.two.clicked.connect(lambda:self.clickedNum('2')) self.three = QPushButton('3') self.three.clicked.connect(lambda:self.clickedNum('3')) self.four = QPushButton('4') self.four.clicked.connect(lambda:self.clickedNum('4')) self.five = QPushButton('5') self.five.clicked.connect(lambda:self.clickedNum('5')) self.six = QPushButton('6') self.six.clicked.connect(lambda:self.clickedNum('6')) self.seven = QPushButton('7') self.seven.clicked.connect(lambda:self.clickedNum('7')) self.eight = QPushButton('8') self.eight.clicked.connect(lambda:self.clickedNum('8')) self.nine = QPushButton('9') self.nine.clicked.connect(lambda:self.clickedNum('9')) self.zero = QPushButton('0') self.zero.clicked.connect(lambda:self.clickedNum('0')) ## calculator ## self.plus = QPushButton('+') self.plus.clicked.connect(lambda:self.clickedNum('+')) self.minus = QPushButton('-') self.minus.clicked.connect(lambda:self.clickedNum('-')) self.division = QPushButton('/') self.division.clicked.connect(lambda:self.clickedNum('/')) self.multiply = QPushButton('*') self.multiply.clicked.connect(lambda:self.clickedNum('*')) self.dot = QPushButton('.') self.dot.clicked.connect(lambda:self.clickedNum('.')) self.squared = QPushButton('x^2') self.squared.clicked.connect(lambda:self.clickedNum('**2')) self.remainder = QPushButton('%') self.remainder.clicked.connect(lambda:self.clickedNum('%')) self.clear = QPushButton('Clear') self.clear.clicked.connect(self.clearText) self.back = QPushButton('Back') self.back.clicked.connect(self.backText) self.enter = QPushButton("=") self.enter.clicked.connect(self.calculateResult) self.lcd = QLineEdit('') self.lcd.setReadOnly(True) self.lcd.setAlignment(Qt.AlignRight) self.lcd.setStyleSheet('font-size:15px;font-weight:bold;padding:10px;') self.label = QLabel('계산기') grid = QGridLayout() grid.setSizeConstraint(QLayout.SetFixedSize) grid.addWidget(self.label, 0, 0, 1, 4, alignment=Qt.AlignCenter) grid.addWidget(self.lcd, 1, 0, 1, 4) grid.addWidget(self.plus, 2, 0) grid.addWidget(self.minus, 2, 1) grid.addWidget(self.multiply, 2, 2) grid.addWidget(self.division, 2, 3) grid.addWidget(self.seven, 3, 0) grid.addWidget(self.eight, 3, 1) grid.addWidget(self.nine, 3, 2) grid.addWidget(self.clear, 3, 3) grid.addWidget(self.four, 4, 0) grid.addWidget(self.five, 4, 1) grid.addWidget(self.six, 4, 2) grid.addWidget(self.back, 4, 3) grid.addWidget(self.one, 5, 0) grid.addWidget(self.two, 5, 1) grid.addWidget(self.three, 5, 2) grid.addWidget(self.squared, 5, 3) grid.addWidget(self.remainder, 6, 0) grid.addWidget(self.zero, 6, 1) grid.addWidget(self.dot, 6, 2) grid.addWidget(self.enter, 6, 3) self.setLayout(grid) self.setWindowTitle("계산기") self.show() def clickedNum(self, text): self.s += text self.lcd.setText(self.s) def calculateResult(self): self.lcd.setText(str(eval(self.s))) self.s = '' def clearText(self): self.lcd.setText('') self.s = '' def backText(self): self.s = self.s[:-1] self.lcd.setText(self.s) def keyPressEvent(self, event): if event.key() == Qt.Key_Return: self.calculateResult() elif event.key() == Qt.Key_Backspace: self.backText() elif event.key() == Qt.Key_Escape: self.close() 프로그램무한반복 = QApplication(sys.argv) 실행인스턴스 = 생선가게POS기() 프로그램무한반복.exec_()
3. 상세 내용
3.1 버튼,기호 표시 및 이벤트 연결
self.one = QPushButton('1') self.one.clicked.connect(lambda:self.clickedNum('1')) self.two = QPushButton('2') self.two.clicked.connect(lambda:self.clickedNum('2')) # ... 중략 ... self.nine = QPushButton('9') self.nine.clicked.connect(lambda:self.clickedNum('9')) self.zero = QPushButton('0') self.zero.clicked.connect(lambda:self.clickedNum('0'))
- 0~9까지의 숫자 버튼을 추가하는 과정입니다. 여기서 lambda를 사용하는 이유는 connect( ) 안에 들어갔던 함수는 파라미터를 줄 경우 동작하지 않기 때문입니다. 즉, "( )" 가 없어야 실행됩니다.
self.plus = QPushButton('+') self.plus.clicked.connect(lambda:self.clickedNum('+')) self.minus = QPushButton('-') self.minus.clicked.connect(lambda:self.clickedNum('-')) # ... 중략 ... self.squared = QPushButton('x^2') self.squared.clicked.connect(lambda:self.clickedNum('**2')) self.remainder = QPushButton('%') self.remainder.clicked.connect(lambda:self.clickedNum('%'))
- 계산 버튼들을 추가하는 과정입니다.
self.clear = QPushButton('Clear') self.clear.clicked.connect(self.clearText) self.back = QPushButton('Back') self.back.clicked.connect(self.backText) self.enter = QPushButton("=") self.enter.clicked.connect(self.calculateResult)
- 그 외에 동작하는 이벤트를 지정해줍니다. 차례 대로 전체 텍스트 지우기, 하나의 텍스트 지우기, 계산을 수행하는 역활을 수행하게 됩니다.
self.lcd = QLineEdit("") self.lcd.setReadOnly(True) self.lcd.setAlignment(Qt.AlignRight) self.lcd.setStyleSheet("font-size:15pt;font-weight:bold;padding:10px;") self.label = QLabel("계산기") grid = QGridLayout() grid.setSizeConstraint(QLayout.SetFixedSize)
- QLineEdit를 이용해 숫자및 기호들을 표시합니다.
- setReadOnly(값): 읽기전용으로 동작합니다. 즉, QLineEdit에서 수정 불가
- QGridLayout를 활용해 행과 열로 버튼들을 구성합니다.
3.2 함수(슬롯) 구현
def clickedNum(self, text): self.s += text self.lcd.setText(self.s)
def calculateResult(self): self.lcd.setText(str(eval(self.s))) self.s = ''
- Enter 즉, 계산처리를 하는 함수
- eval("문자열") 문자열에 따른 계산을 해주는 내장함수(Biltin-functions)
- 코드를 조금 더 업데이트 한다면 try를 통해 먼저 이벤트 처리를 시도하고 에러가 나면 except문에서 처리할 수 있습니다.
def clearText(self): self.lcd.setText('') self.s = '' def backText(self): self.s = self.s[:-1] self.lcd.setText(self.s)
- clear()를통해 사용자가 clear버튼을 누르면 QLineEdit값을 초기화
- 사용자가 back버튼을 클릭하면 문자열 슬라이싱을 통해 QLineEdit에 값을 업데이트
def keyPressEvent(self, event): if event.key() == Qt.Key_Return: self.CalculateResult() elif event.key() == Qt.Key_Backspace: self.backText() elif event.key() == Qt.Key_Escape: self.close()
- 마우스 이벤트를 추가하여 enter, backspace, ESC에 따른 이벤트 처리를 위해 선언했던 함수(슬롯)과 연결
4. 실행 결과








