[python] GUI 계산기

nikevapormax·2022년 4월 6일
0

사전과제

목록 보기
1/3
post-thumbnail

(파이썬 기초 활용편 7) GUI 계산기 만들기 강의 #tkinter

🦧 코딩 계기

파이썬을 혼자 공부하면서 계산기의 '기능'에 대해서는 신물나게 만들어 본 기억이 있다. 이번 내일배움캠프 2기에 합류하게 되면서, 사전 과제로 계산기 코딩에 대해 하게 되면서 코딩나우 님께서 유튭에 올려주신 내용을 보고 기능만이 아닌 기본적이지만 유저 인터페이스까지 구현한 계산기를 만들어 보게 되었다.

🦧 개념

🔥tkinter

  • Tcl/Tk에 대한 파이썬 Wrapper로서 Tcl/Tk를 파이썬에 사용할 수 있도록 한 Lightweight GUI 모듈
    • Tcl : Tool Command Language
    • Tk : 크로스 플랫폼에 사용되는 일종의 GUI 툴킷
  • 장점 : Python 설치시 기본적으로 내장되어 있는 파이썬 표준 라이브러리로 쉽고 간단한 GUI 프로그램을 만들 때 활용
  • 단점 : 지원되는 위젯들이 부족하고 UI도 그렇게 예쁘지 않다

🔥tkinter의 mainloop function

  • 여러 모듈에서 위젯을 생성하고, 트리거를 설정하고 난 뒤 실행흐름 마지막에 user의 입력을계속 기다리게 하는 목적으로 사용
    • 계속 기다리지 않으면 한 번만 실행되고 꺼짐!
      지속적으로 UI를 유지하기 위해서 필요함!
  • 단순히 코드 마지막이 아니라 프로그램 흐름 마지막단에 위치해야 한다!

출처: https://golony777.tistory.com/31 [Golony의 이리 저리사는 이야기]

🔥tkinter의 Button

  • method 또는 function을 실행시킬 수 있는 버튼 생성

  • 나머지 Button의 매개변수 및 파라미터 등은 아래에서 확인

🔥tkinter의 grid

  • grid를 이용하여 위젯을 배치할 수 있다.

🔥tkinter의 Entry

  • 텍스트를 입력받거나 출력하기 위한 기입창을 생성
    즉, 계산기에 입력한 숫자와 결과를 사용자에게 제시하기 위해 사용

출처 : https://076923.github.io/posts/Python-tkinter-3/

🦧 GUI 계산기 코드

🔥전체 코드

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 임포트

# tkinter를 임포트하고 편의를 위해 t로 선언
import tkinter as t

# cal이라는 Tk 클래스 객체 생성 / GUI의 이름 지정
cal = t.Tk()
cal.title("GUI 계산기")

# 객체의 mainloop() 매서드 호출
cal.mainloop()

🔥계산기 인터페이스

  • 하단의 코드를 2중 for문을 활용해 심플하게 표현
  • 계산기의 요소들을 리스트로 선언함으로 인해, 나중에 요소의 값이 바뀌게 되면 리스트의 값만 변경하면 되 코드가 완성된 후 고치기 편함
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)
profile
https://github.com/nikevapormax

0개의 댓글