파이썬을 혼자 공부하면서 계산기의 '기능'에 대해서는 신물나게 만들어 본 기억이 있다. 이번 내일배움캠프 2기에 합류하게 되면서, 사전 과제로 계산기 코딩에 대해 하게 되면서 코딩나우 님께서 유튭에 올려주신 내용을 보고 기능만이 아닌 기본적이지만 유저 인터페이스까지 구현한 계산기를 만들어 보게 되었다.
계속 기다리게 하는 목적
으로 사용출처: https://golony777.tistory.com/31 [Golony의 이리 저리사는 이야기]
method 또는 function을 실행시킬 수 있는 버튼 생성
나머지 Button의 매개변수 및 파라미터 등은 아래에서 확인
import tkinter as t
currValue = 0
# 사칙연산 명령을 처리하기 위해 딕셔너리 형태로 숫자 부여
operator = {'+' :1, '-':2, '/':3, '*':4, 'C':5, '=':6}
storedValue = 0
previousOper = 0
# 버튼 클릭에 대한 변수 생성
def button_click(value):
# 숫자와 오퍼레이터 분리
try:
value = int(value)
number_click(value)
except:
operator_click(value)
def number_click(value):
global currValue #전역변수를 선언.(밖에서 선언된 변수를 해당 함수 안에서도 사용하겠다.)
currValue = (currValue * 10) + value
str_value.set(currValue)
def operator_click(value):
global currValue, operator, storedValue, previousOper
# value에 +, - 등이 들어가면 숫자를 반환
op = operator[value]
if op == 5: # C를 누른 경우
clear()
elif currValue == 0: # 아무것도 눌리지 않은 경우, 값이 없을 때
previousOper = 0
elif previousOper == 0: # 이전 사칙연산 명령이 없고, 명령이 새로 눌렸을 때
previousOper = op
storedValue = currValue
currValue = 0
str_value.set(currValue) # 입력한 숫자를 저장하고, 현재 숫자를 0으로 초기화해서 명령을 누를 때는 0으로 보이게 해줌
elif op == 6: # =을 눌렀을 때
if previousOper == 1: # +를 눌렀을 때 연산 진행. 위의 저장된 값과 명령 이후 친 현재 값을 더함
currValue = storedValue + currValue
elif previousOper == 2: # -를 눌렀을 때 연산 진행. 위의 저장된 값과 명령 이후 친 현재 값을 뺌
currValue = storedValue + currValue
elif previousOper == 3: # /를 눌렀을 때 연산 진행. 위의 저장된 값과 명령 이후 친 현재 값을 나눔
currValue = storedValue + currValue
elif previousOper == 4: # *를 눌렀을 때 연산 진행. 위의 저장된 값과 명령 이후 친 현재 값을 곱함
currValue = storedValue + currValue
str_value.set(str(currValue))
currValue = 0
storedValue = 0
previousOper = 0
else:
clear()
def clear():
global currValue,storedValue, previousOper
currValue = 0
storedValue = 0
previousOper = 0
str_value.set(currValue)
cal = t.Tk()
cal.title("GUI 계산기")
str_value = t.StringVar()
str_value.set(str(currValue)) # currValue의 값을 문자로 변환
# set을 사용하게 되면 textvariable에 입력되어 있는 값이 자동으로 업뎃됨
curr = t.Entry(cal, textvariable=str_value, justify='right', bg='yellow', fg='red')
# 엔트리창 배경색과 폰트색
curr.grid(column=0, row=0, columnspan=4, ipadx=80, ipady=30)
# 계산기의 요소들을 2중 리스트로 표현
cal_item = [['1', '2', '3', '4'],
['5', '6', '7', '8'],
['9', '0', '+', '-'],
['/', '*', 'C', '=']]
for i, items in enumerate(cal_item): # i에는 index가, items에는 하나의 리스트가 들어감
for k, item in enumerate(items): # k에는 items에 받아온 리스트의 index가, item에는 리스트의 각 요소가 들어감
# 예외상황 처리를 응용하여 item의 요소 중 숫자인 것의 배경색은 검은색, 기호의 배경색은 녹색으로 변경
try:
color = int(item)
color = 'black'
except:
color = 'green'
btn = t.Button(cal,
text=item,
width=10,
height=5,
bg=color, # 계산기 배경 색
fg='white', # 계산기 폰트 색
# item을 cmd라는 변수에 넣고 button_click의 인자로 보내는 함수를 람다를 통해 생성
command = lambda cmd = item: button_click(cmd)
)
btn.grid(column=k, row=i+1) # 칼럼은 0부터 시작이니 k로, 로우는 1부터 시작하므로 i+1
cal.mainloop()
# tkinter를 임포트하고 편의를 위해 t로 선언
import tkinter as t
# cal이라는 Tk 클래스 객체 생성 / GUI의 이름 지정
cal = t.Tk()
cal.title("GUI 계산기")
# 객체의 mainloop() 매서드 호출
cal.mainloop()
currValue = 0
str_value = t.StringVar()
str_value.set(str(currValue)) # currValue의 값을 문자로 변환
# set을 사용하게 되면 textvariable에 입력되어 있는 값이 자동으로 업뎃됨
curr = t.Entry(cal, textvariable=str_value, justify='right', bg='yellow', fg='red')
# 엔트리창 배경색과 폰트색
curr.grid(column=0, row=0, columnspan=4, ipadx=80, ipady=30)
# 계산기의 요소들을 2중 리스트로 표현
cal_item = [['1', '2', '3', '4'],
['5', '6', '7', '8'],
['9', '0', '+', '-'],
['/', '*', 'C', '=']]
for i, items in enumerate(cal_item): # i에는 index가, items에는 하나의 리스트가 들어감
for k, item in enumerate(items): # k에는 items에 받아온 리스트의 index가, item에는 리스트의 각 요소가 들어감
# 예외상황 처리를 응용하여 item의 요소 중 숫자인 것의 배경색은 검은색, 기호의 배경색은 녹색으로 변경
try:
color = int(item)
color = 'black'
except:
color = 'green'
btn = t.Button(cal,
text=item,
width=10,
height=5,
bg=color, # 계산기 배경 색
fg='white' # 계산기 폰트 색
)
btn.grid(column=k, row=i+1) # 칼럼은 0부터 시작이니 k로, 로우는 1부터 시작하므로 i+1
t.Button(cal, text='1', width=10, height=5).grid(column=0, row=1)
t.Button(cal, text='2', width=10, height=5).grid(column=1, row=1)
t.Button(cal, text='3', width=10, height=5).grid(column=2, row=1)
t.Button(cal, text='4', width=10, height=5).grid(column=3, row=1)
t.Button(cal, text='5', width=10, height=5).grid(column=0, row=2)
t.Button(cal, text='6', width=10, height=5).grid(column=1, row=2)
t.Button(cal, text='7', width=10, height=5).grid(column=2, row=2)
t.Button(cal, text='8', width=10, height=5).grid(column=3, row=2)
t.Button(cal, text='9', width=10, height=5).grid(column=0, row=3)
t.Button(cal, text='0', width=10, height=5).grid(column=1, row=3)
t.Button(cal, text='+', width=10, height=5).grid(column=2, row=3)
t.Button(cal, text='-', width=10, height=5).grid(column=3, row=3)
t.Button(cal, text='/', width=10, height=5).grid(column=0, row=4)
t.Button(cal, text='*', width=10, height=5).grid(column=1, row=4)
t.Button(cal, text='C', width=10, height=5).grid(column=2, row=4)
t.Button(cal, text='=', width=10, height=5).grid(column=3, row=4)
currValue = 0
# 사칙연산 명령을 처리하기 위해 딕셔너리 형태로 숫자 부여
operator = {'+' :1, '-':2, '/':3, '*':4, 'C':5, '=':6}
storedValue = 0
previousOper = 0
# 버튼 클릭에 대한 변수 생성
def button_click(value):
# 숫자와 오퍼레이터 분리
try:
value = int(value)
number_click(value)
except:
operator_click(value)
def number_click(value):
global currValue #전역변수를 선언.(밖에서 선언된 변수를 해당 함수 안에서도 사용하겠다.)
currValue = (currValue * 10) + value
str_value.set(currValue)
def operator_click(value):
global currValue, operator, storedValue, previousOper
# value에 +, - 등이 들어가면 숫자를 반환
op = operator[value]
if op == 5: # C를 누른 경우
clear()
elif currValue == 0: # 아무것도 눌리지 않은 경우, 값이 없을 때
previousOper = 0
elif previousOper == 0: # 이전 사칙연산 명령이 없고, 명령이 새로 눌렸을 때
previousOper = op
storedValue = currValue
currValue = 0
str_value.set(currValue) # 입력한 숫자를 저장하고, 현재 숫자를 0으로 초기화해서 명령을 누를 때는 0으로 보이게 해줌
elif op == 6: # =을 눌렀을 때
if previousOper == 1: # +를 눌렀을 때 연산 진행. 위의 저장된 값과 명령 이후 친 현재 값을 더함
currValue = storedValue + currValue
elif previousOper == 2: # -를 눌렀을 때 연산 진행. 위의 저장된 값과 명령 이후 친 현재 값을 뺌
currValue = storedValue + currValue
elif previousOper == 3: # /를 눌렀을 때 연산 진행. 위의 저장된 값과 명령 이후 친 현재 값을 나눔
currValue = storedValue + currValue
elif previousOper == 4: # *를 눌렀을 때 연산 진행. 위의 저장된 값과 명령 이후 친 현재 값을 곱함
currValue = storedValue + currValue
str_value.set(str(currValue))
currValue = 0
storedValue = 0
previousOper = 0
else:
clear()
def clear():
global currValue,storedValue, previousOper
currValue = 0
storedValue = 0
previousOper = 0
str_value.set(currValue)