6.8 계산기 구현하기
728x90

1. 계산기 예제 준비하기
더보기
import sys
from PySide6.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QGridLayout
from PySide6.QtCore import Qt
class CalculatorWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("계산기")
self.setMinimumSize(336, 541)
# [1] 그리드 레이아웃 생성
layout = QGridLayout(self)
layout.setSpacing(4)
layout.setContentsMargins(4, 4, 4, 4)
# 행/열 구조는 “실제 칸” 기준으로 단순화
# 열: 4열 (%, CE, C, ⌫ 처럼)
# 행: 결과 표시 + 5줄 버튼 = 총 6~7줄 정도
# [2] 결과 라벨
self.result_label = QLabel("0")
self.result_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.result_label.setStyleSheet("font-size: 36px; padding: 8px;")
# row=0, column=0~3(span 4)
layout.addWidget(self.result_label, 0, 0, 1, 4)
# [3] 1줄: %, CE, C, ⌫
btn_percent = QPushButton("%")
btn_ce = QPushButton("CE")
btn_c = QPushButton("C")
btn_del = QPushButton("⌫")
for b in (btn_percent, btn_ce, btn_c, btn_del):
b.setMinimumHeight(50)
layout.addWidget(btn_percent, 1, 0)
layout.addWidget(btn_ce, 1, 1)
layout.addWidget(btn_c, 1, 2)
layout.addWidget(btn_del, 1, 3)
# [4] 2줄: 1/x, x², √x, ÷
btn_inv = QPushButton("1/x")
btn_sq = QPushButton("x²")
btn_sqrt = QPushButton("√x")
btn_div = QPushButton("÷")
for b in (btn_inv, btn_sq, btn_sqrt, btn_div):
b.setMinimumHeight(50)
layout.addWidget(btn_inv, 2, 0)
layout.addWidget(btn_sq, 2, 1)
layout.addWidget(btn_sqrt, 2, 2)
layout.addWidget(btn_div, 2, 3)
# [5] 3줄: 7 8 9 ×
btn_7 = QPushButton("7")
btn_8 = QPushButton("8")
btn_9 = QPushButton("9")
btn_mul = QPushButton("×")
for b in (btn_7, btn_8, btn_9, btn_mul):
b.setMinimumHeight(50)
layout.addWidget(btn_7, 3, 0)
layout.addWidget(btn_8, 3, 1)
layout.addWidget(btn_9, 3, 2)
layout.addWidget(btn_mul, 3, 3)
# [6] 4줄: 4 5 6 −
btn_4 = QPushButton("4")
btn_5 = QPushButton("5")
btn_6 = QPushButton("6")
btn_sub = QPushButton("−")
for b in (btn_4, btn_5, btn_6, btn_sub):
b.setMinimumHeight(50)
layout.addWidget(btn_4, 4, 0)
layout.addWidget(btn_5, 4, 1)
layout.addWidget(btn_6, 4, 2)
layout.addWidget(btn_sub, 4, 3)
# [7] 5줄: 1 2 3 +
btn_1 = QPushButton("1")
btn_2 = QPushButton("2")
btn_3 = QPushButton("3")
btn_add = QPushButton("+")
for b in (btn_1, btn_2, btn_3, btn_add):
b.setMinimumHeight(50)
layout.addWidget(btn_1, 5, 0)
layout.addWidget(btn_2, 5, 1)
layout.addWidget(btn_3, 5, 2)
layout.addWidget(btn_add, 5, 3)
# [8] 6줄: +/- 0 . =
btn_neg = QPushButton("+/-")
btn_0 = QPushButton("0")
btn_point = QPushButton(".")
btn_eq = QPushButton("=")
for b in (btn_neg, btn_0, btn_point, btn_eq):
b.setMinimumHeight(50)
layout.addWidget(btn_neg, 6, 0)
layout.addWidget(btn_0, 6, 1)
layout.addWidget(btn_point, 6, 2)
layout.addWidget(btn_eq, 6, 3)
# [9] 행 비율(스트레치) 설정 (선택)
# 결과 라벨이 조금 더 많이 공간을 차지하게 하고 싶으면:
layout.setRowStretch(0, 1) # 레이블 줄 (작게)
layout.setRowStretch(1, 2) # 버튼 줄 (크게)
layout.setRowStretch(2, 2)
layout.setRowStretch(3, 2)
layout.setRowStretch(4, 2)
layout.setRowStretch(5, 2)
layout.setRowStretch(6, 2)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = CalculatorWindow()
w.show()
sys.exit(app.exec())
2. 계산기 예제 준비하기
더보기
import sys
from PySide6.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QGridLayout
from PySide6.QtCore import Qt
class CalculatorLayoutDemo(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("계산기 레이아웃 데모")
self.setMinimumSize(336, 541)
# [1] QGridLayout 생성
layout = QGridLayout(self)
layout.setSpacing(4) # 버튼 사이 간격
layout.setContentsMargins(4, 4, 4, 4) # 바깥 여백
# [2] 결과 표시 라벨 (0번째 행, 0~3열 span)
self.result_label = QLabel("0")
self.result_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.result_label.setStyleSheet("font-size: 36px; padding: 8px;")
layout.addWidget(self.result_label, 0, 0, 1, 4)
# [3] 계산기 버튼 텍스트를 2차원 리스트(행렬)로 정의
buttons = [
["%", "CE", "C", "⌫"],
["1/x", "x²", "√x", "÷"],
["7", "8", "9", "×"],
["4", "5", "6", "−"],
["1", "2", "3", "+"],
["+/-", "0", ".", "="],
]
# [4] 버튼 생성 및 그리드에 배치
# - result_label이 0행에 있으므로 버튼은 1행부터 시작
# - row_offset = 1
row_offset = 1
# 버튼 객체를 나중에 쓰고 싶으면 dict에 보관해도 됨
self.button_map = {}
for row_index, row in enumerate(buttons):
for col_index, text in enumerate(row):
btn = QPushButton(text)
# 버튼 동일 높이
btn.setMinimumHeight(50)
# 그리드에 배치
grid_row = row_offset + row_index
grid_col = col_index
layout.addWidget(btn, grid_row, grid_col)
# 나중에 사용할 수 있도록 보관 (텍스트 기준)
self.button_map[text] = btn
# 예: 특정 버튼에 스타일 지정도 가능
if "=" in self.button_map:
self.button_map["="].setStyleSheet("font-weight: bold; font-size: 18px;")
# [5] 행 스트레치 설정(선택) - 위쪽/아래쪽 공간 비율 조정
# 0행: 결과 라벨 줄
layout.setRowStretch(0, 1)
# 버튼 줄(1~6행)을 동일 비율로 늘리기
for r in range(1, 7):
layout.setRowStretch(r, 2)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = CalculatorLayoutDemo()
w.show()
sys.exit(app.exec())
3. 덧셈 기능만 구현
더보기
import sys
from PySide6.QtWidgets import (
QApplication, QWidget, QLabel, QPushButton, QGridLayout
)
from PySide6.QtCore import Qt
class CalculatorLayoutDemo(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("계산기 (덧셈 기능만)")
self.setMinimumSize(336, 541)
# ======== 계산 상태 변수 ========
self.current_input = "0" # 화면에 표시되는 현재 입력
self.saved_value = None # 이전 값 (덧셈용)
self.is_add_mode = False # + 버튼 눌러진 상태 여부
# ======== [1] 레이아웃 ========
layout = QGridLayout(self)
layout.setSpacing(4)
layout.setContentsMargins(4, 4, 4, 4)
# ======== [2] 결과 표시 ========
self.result_label = QLabel("0")
self.result_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.result_label.setStyleSheet("font-size: 36px; padding: 8px;")
layout.addWidget(self.result_label, 0, 0, 1, 4)
# ======== [3] 버튼 행렬 ========
buttons = [
["%", "CE", "C", "⌫"],
["1/x", "x²", "√x", "÷"],
["7", "8", "9", "×"],
["4", "5", "6", "−"],
["1", "2", "3", "+"],
["+/-", "0", ".", "="],
]
self.button_map = {}
row_offset = 1
for r, row in enumerate(buttons):
for c, text in enumerate(row):
btn = QPushButton(text)
btn.setMinimumHeight(50)
layout.addWidget(btn, row_offset + r, c)
self.button_map[text] = btn
# ======== 버튼 기능 연결 ========
# 숫자 버튼
for num in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]:
self.button_map[num].clicked.connect(self.on_number_clicked)
# 덧셈
self.button_map["+"].clicked.connect(self.on_plus_clicked)
# =
self.button_map["="].clicked.connect(self.on_equal_clicked)
# 초기값 표시
self.update_display()
# 숫자 입력 처리
def on_number_clicked(self):
text = self.sender().text()
if self.current_input == "0":
self.current_input = text
else:
self.current_input += text
self.update_display()
# + 동작 (덧셈 모드 진입)
def on_plus_clicked(self):
self.saved_value = float(self.current_input)
self.current_input = "0"
self.is_add_mode = True
self.update_display()
# = 동작 (덧셈 계산 실행)
def on_equal_clicked(self):
if self.is_add_mode and self.saved_value is not None:
result = self.saved_value + float(self.current_input)
self.current_input = str(result)
self.is_add_mode = False
self.saved_value = None
self.update_display()
# 화면 업데이트
def update_display(self):
self.result_label.setText(self.current_input)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = CalculatorLayoutDemo()
w.show()
sys.exit(app.exec())