Lang/Python

Tkinter 로 계산기 만들기

Henu 2020. 6. 18. 00:45

사칙연산 계산기를 만들어 봄

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from tkinter import *
 
class calculator:
    def __init__(self, win):
        self.win = win
        self.win.title("계산기")
        self.win.geometry("320x245+200+100")
        self.win.resizable(TrueTrue)    
 
        self.process = Entry(win, width = 40, justify = RIGHT)
        self.process.insert(0'0')
        self.process.pack()
 
        self._input = Entry(win, width = 40, justify = RIGHT)
        self._input.insert(0,'0')
        self._input.pack()
 
        self.frm = Frame(self.win)
        self.frm.pack()
        self.cal_component = "789*456-123+C0./"
 
        # 계산기의 버튼을 만드는 반복문 grid 사용
        self.ind = 0
        for row in range(4):
            for col in range(4):
                btn = Button(self.frm, text = self.cal_component[self.ind], relief = GROOVE, width=10, height=2,\
                    command = lambda char = self.cal_component[self.ind]:self.operater(char))
                btn.grid(row = row, column = col)
                self.ind+=1
        btn = Button(self.frm, text = '=', relief=GROOVE, width=10, height=2,\
            command = lambda char = '=' : self.operater(char))
        btn.grid(row = 4, column = 0)
        self.bf_num = 0
        self.operation = ''
 
    def operater(self, n):
        if n == "C":
            self.process.delete(0, END)
            self._input.delete(0, END)
            self.process.insert(00)
            self._input.insert(00)
            self.bf_num = 0
            self.operation = ''
 
        elif n in "+-*/":
            self.process.insert(END, n)
            self.operate()
            self.operation = n
            self.bf_num = eval(self._input.get())
            self._input.delete(0, END)
 
        elif n == '=':
            self.process.insert(END, n)
            self.operate()
            self.operation = ''
            self.process.insert(END, self.bf_num)
        
        elif self._input.get() == '0':
            self._input.delete(0, END)
            self._input.insert(END, n)
            self.process.delete(0, END)
            self.process.insert(END, n)
 
        else:
            self._input.insert(END, n)
            self.process.insert(END, n)
 
    def operate(self):
        if self.operation == '+':
            self.bf_num += eval(self._input.get())
            self.operation = ''
            self._input.delete(0, END)
            self._input.insert(0self.bf_num)
        elif self.operation == '*':
            self.bf_num *= eval(self._input.get())
            self.operation = ''
            self._input.delete(0, END)
            self._input.insert(0self.bf_num)
        elif self.operation == '-':
            self.bf_num -= eval(self._input.get())
            self.operation = ''
            self._input.delete(0, END)
            self._input.insert(0self.bf_num)
        elif self.operation == '/':
            if self._input.get() == '0':
                self._input.delete(0, END)
                self._input.insert(0"0으로 나눌 수 없습니다")
            self.bf_num /= eval(self._input.get())
            self.operation = ''
            self._input.delete(0, END)
            self._input.insert(0self.bf_num)
 
if __name__ == "__main__":
    window = Tk()
    mycal = calculator(window)
    window.mainloop()
 
cs

사용한 위젯

win = Tk()

win은 프로그램의 가장 큰 틀이라고 할 수 있을것 같다

title("계산기")  - 프로그램 상태창에 있는 이름을 정하는 위젯

geometry("300x300+100+50") - 300x300의 크기를 가지고, 모니터 좌측 상단에서 가로로 100픽셀, 세로로 50픽셀 만큼 떨어진 곳에 프로그램의 좌측 상단이 위치함

resizeable(True, False) - 가로는 크기변경이 가능하고 세로는 불가능

 

process = Entry(win, ) - process라는 이름을 가진 입력창을 하나 만들어준다, 좌우 길이 설정이 가능함, 입력창의 좌우 정렬상태를 justify로 설정가능 (justify=RIGHT) -> 오른쪽 정렬

process.insert(0, "hi") - 방금 만든 입력창(process)의 0번 째 위치에 hi라는 문자열을 입력한다.(문자열만 입력가능)

process.pack() - process입력창을 win에 포함시켜준다

 

frm = Frame(win) - win에 하나의 가상의 박스?를 추가해 준다

마찬가지로 frm.pack()을 해줘야 마무리된다

 

btn = Button(frm, text='?', relief=GROOVE, command = lambda ---)

방금 만든 frm 박스에 버튼 기능을 만들어준다

text는 버튼을 설명하는 문자열이 들어간다

relief는 버튼의 모양을 설정해 줄 수있다 GROOVE, RAISE, HIDDEN 등등 여러개가 있더라

추가로 높이(height)와 길이(width), 버튼의 배경색(bg), 버튼의 글자색(fg), 글꼴(font) 등등 다 설정 가능하다

그리고 command는 버튼을 누르면 실행되는 함수를 입력할 수 있는데 주로 lambda를 사용한다

 

command = lambda char = self.cal_component[self.ind]:self.operater(char)) 이런식으로 사용했는데 

command = lambda : self.operator(self.cal_component[self.ind]) 라고 쓰면 왜 string index error가 나는지 잘 모르겠다

이 부분을 간결하게 고치고 싶은데 어디 물어볼 곳도 없고 갑갑하다ㅠㅠ

 

만들어진 버튼의 위치를 지정해 주기위해 btn.grid(row = ?, column=?)를 사용했다

가상의 표를 만들어서 입력된 행과 열에 버튼을 만들어주는 기능이다

 

연산을 해주는 함수 부분에서

_input.get() - 현재 _input에 있는 문자열을 반환해준다

_input.delete(0, END) - 현재 _input에 있는 0번째 부터 끝까지의 문자를 삭제한다 

* insert(시작지점, 입력할 문자열), delete(시작지점, 끝지점)

 

키보드로도 입력받고 싶은데 방법을 알아보고 추가해야겠다