본문 바로가기
파이썬

파이썬 Tkinter 패키지로 계산기 코드 작성

by ㈜㎹Ω∞ 2022. 7. 16.
728x90

Tkinter 패키지로 계산기 코드를 만들어보겠습니다. 코드가 꽤나 길고, 구성도 완벽하지 않습니다.. 조금 더 간편하고 짧은 코드로 만들기 위해 공부중입니다.

 

계산기 만들기

0~9,+(더하기), -(빼기), *(곱하기), /(나누기), =(결과), .(점) 버튼을 만들고, 각각의 버튼을 누르면 계산해주는 함수를 작성하면 됩니다.

 

  • Tkinter, Tkinter.font, title, Button, Font, global, Label, sticky, grid, row, column, config, for, set, int, lambda, padx, pady, command, cget, textvariable, mainloop() 등등 사용

 

실행코드

 

### 실행코드
import tkinter as tk
import tkinter.font as tkf

window = tk.Tk()
window.title("계산기")
font=tkf.Font(family="맑은고딕",size=25)
font2=tkf.Font(family="맑은고딕",size=50)

label_result=tk.Label(window,textvariable=str_value,font=font2)
label_result.grid(row=0, column=0,columnspan=5,sticky="news")

button1=tk.Button(window,text="1")
button1.grid(row=1, column=1)
button2=tk.Button(window,text="2")
button2.grid(row=1, column=2)
button3=tk.Button(window,text="3")
button3.grid(row=1, column=3)
button4=tk.Button(window,text="4")
button4.grid(row=2, column=1)
button5=tk.Button(window,text="5")
button5.grid(row=2, column=2)
button6=tk.Button(window,text="6")
button6.grid(row=2, column=3)
button7=tk.Button(window,text="7")
button7.grid(row=3, column=1)
button8=tk.Button(window,text="8")
button8.grid(row=3, column=2)
button9=tk.Button(window,text="9")
button9.grid(row=3, column=3)
button10=tk.Button(window,text="0")
button10.grid(row=4, column=2)
button11=tk.Button(window,text="+")
button11.grid(row=4, column=1)
button12=tk.Button(window,text="-")
button12.grid(row=4, column=3)
button13=tk.Button(window,text="*")
button13.grid(row=2, column=4)
button14=tk.Button(window,text="/")
button14.grid(row=3, column=4)
button_resul=tk.Button(window,text="=")
button_resul.grid(row=4, column=4)
button_clear=tk.Button(window,text="C")
button_clear.grid(row=1, column=4)

buttons=[button1,button2,button3,button4,button5,button6,button7,button8,button9,
button10,button11,button12,button13,button14,button_resul,button_clear]

for button in buttons:
    button.grid(sticky="news",padx=5,pady=5)
    button.config(font=font,width=3,height=2)
    button.config(command=lambda cmd=button.cget("text"):button_click(cmd))

window.mainloop()

 

실행코드입니다. 나눠서 설명합니다.

 

import tkinter as tk
import tkinter.font as tkf

window = tk.Tk()
window.title("계산기")	### 제목설정
font=tkf.Font(family="맑은고딕",size=20)	### 폰트정하기
font2=tkf.Font(family="맑은고딕",size=50)	### 폰트정하기2

 

import 해서 tkinter와 tkinter.font를 불러옵니다. 이름이 길어서 tkinter는 tk로, tkinter.font는 tkf로 사용합니다. window는 tk모듈의 Tk클래스를 사용해서 만든 객체입니다. title로 이름을 정하고, tkf.Font로 글꼴이랑 크기를 설정합니다.

 

label_result=tk.Label(window,textvariable=str_value,font=font2)	### 라벨설정
label_result.grid(row=0, column=0,columnspan=5,sticky="news")	### 위젯배치

 

  • label_result객체를 만들어서(window,textvariable=str_value,font=font2)를 입력합니다.
  • font=font2는 아까 만든 font2를 사용한다는 뜻이고, "textvariable=str_value" 이 부분은 아직 함수를 안 만들었으니 실행하면 오류가 뜹니다. 그러니 textvariable="미정" 또는 text="미정"이라고 입력해서 실행은 되게 만듭니다.
  • 라벨을 만들었으면 grid를 사용해서 위젯을 배치합니다. (row=행(가로), column=열(세로)입니다. columnspan=가로로 몇 칸을 늘릴지, sticky=어느 방향으로 늘릴지 선택)
  • label_result.grid(row=0, column=0,columnspan=5,sticky="news") : 0행0열의 가로로5칸 모든 방향으로 늘린다는 코드

 

### 1부터10까지는 숫자를 입력합니다.
button1=tk.Button(window,text="1")	### 버튼설정
button1.grid(row=1, column=1)	### 위젯배치
### 11부터14는 +-*/ 를 입력합니다.
button11=tk.Button(window,text="+")
button11.grid(row=4, column=1)
### 결과를 나타내는 =는 button_resul라고 만듭니다.
button_resul=tk.Button(window,text="=")
button_resul.grid(row=4, column=4)
### 리셋시키는 C는 button_clear라고 만듭니다.
button_clear=tk.Button(window,text="C")
button_clear.grid(row=1, column=4)

 

버튼을 총 16개 버튼을 만들어주는데, C와=버튼은 이름을 조금 다르게 입력합니다. (button1처럼 button15라고 입력해도 상관없습니다.)

 

buttons=[button1,button2,button3,button4,button5,button6,button7,button8,button9,
button10,button11,button12,button13,button14,button_resul,button_clear]

for button in buttons:
    button.grid(sticky="news",padx=5,pady=5)	### 위젯배치
    button.config(font=font,width=3,height=2)	### 위젯속성값
    button.config(command=lambda cmd=button.cget("text"):button_click(cmd))	### 실행코드
    
### 실행코드해석

button.config(command=lambda 1번cmd=button.cget("text"):button_click(2번cmd))

 

  • 이제 위젯을 설정해줘야 되는데 버튼 하나하나에 입력할려면 너무 힘드니, buttons=[button1,button2,...] 이렇게 리스트로 만들어줍니다. 리스트로만든 버튼들을 for문을 이용해서 위젯을 설정합니다.
  • for button in buttons: for문을 사용하면 button변수를 정하고 buttons만큼 반복합니다.
  • grid가 위젯배치라면 config는 위젯속성값입니다.(padx=가로여백, pady=세로여백, width=넓이, height=높이)
  • 버튼들마다 x,y 5씩 띄우고 속성값은 넓이3, 높이2 크기로 만듭니다.
  • 마지막으로 계산기 기능을 해주는 코드인데 command를 사용해서 lambda를 연결해서 사용합니다. button.cget("text")는 버튼의 text값을 갖고 와서 그 값을 1번 cmd에 저장하고, 1번 cmd값을 2번으로 보내는 겁니다. 2번에 값이 입력되면 button_click함수로 이동합니다.

 

 

함수코드

 

### 함수코드
present_value, stored_value=0,0
str_value=tk.StringVar()
str_value.set(str(present_value))
operator={"+":1,"-":2,"*":3,"/":4,"C":5,"=":6}
opPre=0

def number_click(value):
    global present_value
    present_value=(present_value*10)+value
    str_value.set(str(present_value))

def operator_click(value):
    global present_value,stored_value,operator,opPre
    op = operator[value]
    if op == 5:
        present_value = 0
        stored_value = 0
        opPre = 0
        str_value.set(str(present_value))
    elif present_value == 0:
        opPre = 0
    elif opPre == 0:
        opPre = op
        stored_value = present_value
        present_value = 0
        str_value.set(str(present_value))
        print(stored_value)
    elif op == 6:
        if opPre == 1:
            present_value = stored_value + present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0
        if opPre == 2:
            present_value = stored_value - present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0
        if opPre == 3:
            present_value = stored_value * present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0
        if opPre == 4:
            present_value = stored_value / present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0

def button_click(value):
    try:
        value=int(value)
        number_click(value)
    except:
        operator_click(value)

 

함수코드입니다. 나눠서 설명합니다.

 

present_value, stored_value=0,0	### 변수설정
str_value=tk.StringVar()	### StringVar로정함
str_value.set(str(present_value))	### 처음실행하면나오는값0

def number_click(value):
    global present_value	### 전역변수선언
    1.present_value=(2.present_value*10)+3.value	### 버튼값입력
    str_value.set(str(present_value))	### 버튼누르면 나오는값

 

  • present_value=현재값stored_value=저장된값을 각각 0으로 설정하고 StringVar()을 사용해서 값을 정합니다.
  • str_value=StringVar() 객체를 정했다면 str_value.set(str(present_value))로 라벨에 0이 표시되게 합니다. (set()을 사용해서 값을 정하고, get()을 사용해서 값을 가져옵니다.)
  • global을 사용해서 present_value를 전역변수를 사용합니다. 
  • 1번present_value는 2번 present_value의 현재값에서 10을 곱한뒤(자릿수가 하나커짐) 3번 value를 더한값을 1번present_value에 저장합니다.
  • str_value.set(str(present_value))를 입력해서 str_value값을 변환해줍니다.
  • str_value는 label_result=tk.Label(window,textvariable="미정",font=font)의 미정으로 작성한 부분에 str_value라고 바꿔주면 됩니다.

 

operator={"+":1,"-":2,"*":3,"/":4,"C":5,"=":6}
opPre=0	### operator값 저장
def operator_click(value):
    global present_value,stored_value,operator,opPre
    op = operator[value]
    ###전부삭제
    if op == 5:
        present_value = 0
        stored_value = 0
        opPre = 0
        str_value.set(str(present_value))
    ### 초기화면,
    elif present_value == 0:
        opPre = 0
    ### 아무것도 입력안되있을때
    elif opPre == 0:
        opPre = op
        stored_value = present_value
        present_value = 0
        str_value.set(str(present_value))
        print(stored_value)	### 없어도됩니다.
    ### op가 6이라면
    elif op == 6:
    	### 더하기
        if opPre == 1:
            present_value = stored_value + present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0
        ### 빼기
        if opPre == 2:
            present_value = stored_value - present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0
        ### 곱하기
        if opPre == 3:
            present_value = stored_value * present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0
        ### 나누기
        if opPre == 4:
            present_value = stored_value / present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0

 

위에 함수는 +-*/=C를 클릭했을때 실행하는 함수입니다. operator=딕셔너리로 키와 값을 만들고, opPre=0을 만듭니다. global을 사용해서 전역변수를 선언합니다. op = operator[value] "+"를 입력했다면 1이 value에 들어가고 그 값이 op에 저장됩니다.

  1. if op == 5: 만약 입력값이 5(C입니다)라면, 현재 값, 저장된 값, opPre전부다 0으로 만들고 라벨에 0을 표시합니다.
  2. present_value == 0: 현재 값이 0이라면 opPre도 0입니다.(아무것도 입력 안 했을 시)
  3. opPre == 0 : opPre가 0이라면 opPre에 op값을 넣어줍니다. (op값은 operator값) 저장된 값에는 현재 값을 넣어주고, 그 뒤 현재 값은 0이 됩니다. 라벨에 0이 나오게 해 줍니다.(print(stored_value) 부분은 없어도 됩니다. 있으면 터미널 부분에 누른 숫자가 뜹니다.)
  4. op가 6인데 (=을 눌렀을 때) opPre가 1이라면(+더하기) 현재 값은 저장된 값+현재 값이 저장되고, 라벨에 표시한다. 그 뒤 현재 값, 저장된 값, opPre는  0으로 만든다.
  5. op=6 부분의 if 1~4는 present_value = stored_value + present_value의 +부분의 기호를 -(빼기), *(곱하기), /(나누기)로 바꿔주기만 하면 더하기, 빼기, 곱하기, 나누기 함수가 완성됩니다.

 

def button_click(value):
    try:
        value=int(value)
        number_click(value)
    except:
        operator_click(value)

 

try로 해야 할 일과 except로 오류 났을 때 할 일을 설정해줬습니다. 값이 들어오면 정수로 바꿔주고 그 값을 number_click으로 보내줍니다. 에러가 날 경우 operator_click을 실행합니다.

 

전체코드

 

# 전체코드
import tkinter as tk
import tkinter.font as tkf

window = tk.Tk()
window.title("계산기")
font=tkf.Font(family="맑은고딕",size=25)
font2=tkf.Font(family="맑은고딕",size=50)

### 함수부분
present_value, stored_value=0,0
str_value=tk.StringVar()
str_value.set(str(present_value))
operator={"+":1,"-":2,"*":3,"/":4,"C":5,"=":6}
opPre=0

def number_click(value):
    global present_value
    present_value=(present_value*10)+value
    str_value.set(str(present_value))

def operator_click(value):
    global present_value,stored_value,operator,opPre
    op = operator[value]
    if op == 5:
        present_value = 0
        stored_value = 0
        opPre = 0
        str_value.set(str(present_value))
    elif present_value == 0:
        opPre = 0
    elif opPre == 0:
        opPre = op
        stored_value = present_value
        present_value = 0
        str_value.set(str(present_value))
        print(stored_value)
    elif op == 6:
        if opPre == 1:
            present_value = stored_value + present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0
        if opPre == 2:
            present_value = stored_value - present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0
        if opPre == 3:
            present_value = stored_value * present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0
        if opPre == 4:
            present_value = stored_value / present_value        
            str_value.set(str(present_value))
            present_value = 0
            stored_value = 0
            opPre = 0

def button_click(value):
    try:
        value=int(value)
        number_click(value)
    except:
        operator_click(value)

label_result=tk.Label(window,textvariable=str_value,font=font2)
label_result.grid(row=0, column=0,columnspan=5,sticky="news")

button1=tk.Button(window,text="1")
button1.grid(row=1, column=1)
button2=tk.Button(window,text="2")
button2.grid(row=1, column=2)
button3=tk.Button(window,text="3")
button3.grid(row=1, column=3)
button4=tk.Button(window,text="4")
button4.grid(row=2, column=1)
button5=tk.Button(window,text="5")
button5.grid(row=2, column=2)
button6=tk.Button(window,text="6")
button6.grid(row=2, column=3)
button7=tk.Button(window,text="7")
button7.grid(row=3, column=1)
button8=tk.Button(window,text="8")
button8.grid(row=3, column=2)
button9=tk.Button(window,text="9")
button9.grid(row=3, column=3)
button10=tk.Button(window,text="0")
button10.grid(row=4, column=2)
button11=tk.Button(window,text="+")
button11.grid(row=4, column=1)
button12=tk.Button(window,text="-")
button12.grid(row=4, column=3)
button13=tk.Button(window,text="*")
button13.grid(row=2, column=4)
button14=tk.Button(window,text="/")
button14.grid(row=3, column=4)
button_resul=tk.Button(window,text="=")
button_resul.grid(row=4, column=4)
button_clear=tk.Button(window,text="C")
button_clear.grid(row=1, column=4)

buttons=[button1,button2,button3,button4,button5,button6,button7,button8,button9,
button10,button11,button12,button13,button14,button_resul,button_clear]

for button in buttons:
    button.grid(sticky="news",padx=5,pady=5)
    button.config(font=font,width=3,height=2)
    button.config(command=lambda cmd=button.cget("text"):button_click(cmd))

window.mainloop()

 

위에코드는 완성된 코드입니다. 복사해서 사용하면 바로 실행 가능한 계산기 코드입니다.

728x90

댓글