본문 바로가기
Python/GUI(tkinter)

독학 Python tkinter(GUI) - 15.Combobox

by To올라운더 2023. 11. 13.
반응형

콤보박스(Combobox)는 드랍다운 형식으로 결과 값이나 텍스트를 목록 형식으로 보여주는 기능을 말한다.

말로는 조금 어려울 수 있지만 콤보박스 또한 사용자가 다른 프로그램을 통해 흔히 봐왔던 기능이고,

단순히 보면 이런 목록 형태로 선택을 하는 기능이다.

 

1. 코드

 - 지난 시간 사용했던 radiobutton도 여러 항목 중 하나를 선택하는 기능을 가지고 있었다.

 - 그런데, radiobutton을 만들었을 때 적용했던 연령 그룹을 좀 더 세분화하여 나누거나 나이를 입력 받으려하면, radiobutton 보다는 combobox가 더 적합한 기능이 된다.

 

  - 내용 비교를 위해 radiobutton과 함께 나타내보겠다.

  - combobox를 사용하기 위해서는 tkinter.kkt 라이브러리가 필요하다.

from tkinter import *
import tkinter.ttk

root = Tk()
root.title('To올라운드의 알찬 GUI 강의')



root.geometry("300x500") # 가로 X 세로 / 대문자X 하면 실행안됨

#msb.showinfo('Welcome','안녕하세요. To올라운더와 함께 하는 GUI입니다.')

body_frame = Frame(root, relief='solid', bd=2, background='orange', padx=5, pady=5)
body_frame.pack(fill='both', expand=True)


# age_group_frame = Frame(body_frame, relief='solid', bd=2, background='orange', padx=5, pady=5)
# age_group_frame.pack()

# age_group_label = Label(age_group_frame, text='* 연령 그룹 선택')
# age_group_label.pack()

age_group_labelframe = LabelFrame(body_frame, text='연령 그룹 선택', relief='solid', bd=2, background='orange', padx=5, pady=5)
age_group_labelframe.pack()

age_group_value = IntVar()

age_group1 = Radiobutton(age_group_labelframe, text='미취학 아동(8세 미만)', value=1, variable=age_group_value)
age_group1.pack(anchor='nw')

age_group2 = Radiobutton(age_group_labelframe, text='초등학생(8 ~ 13세)', value=2, variable=age_group_value)
age_group2.pack(anchor='nw')

age_group3 = Radiobutton(age_group_labelframe, text='청소년(14 ~ 19세)', value=3, variable=age_group_value)
age_group3.pack(anchor='nw')

age_group4 = Radiobutton(age_group_labelframe, text='성인(20세 이상)', value=4, variable=age_group_value)
age_group4.pack(anchor='nw')

age_group_value.set(value=4) # radiobutton 기본 값 설정




age1_label = Label(body_frame, text='나이 : ')
age1_label.pack()

age1_list = [str(age)+'세' for age in range(1,120)]

age1_input_combobox = tkinter.ttk.Combobox(body_frame, height=3, values=age1_list)
age1_input_combobox.pack()

age1_input_combobox.set('나이를 선택하세요.')

quit_btn = Button(body_frame, text='종료', command=quit)
quit_btn.pack(fill='x')


root.resizable(False,False) # x너비, y 변경 허용 여부
root.mainloop()
반응형

  - radiobutton은 항목이 10개면 10개를 모두 해당 윈도우 상에 보여줘야 선택이 가능하지만,

    combobox는 전체가 보이지 않아도 찾아서 선택이 가능하다.

    (* 예시 코드에서 보듯이 120개의 age1_list 항목이 윈도우 상에서는 1칸의 영역만을 사용하는 것을 볼 수 있다.)

 

 - 그런데, 간혹 사용자에게 직접 입력 받는 Entry를 쓰면 되지, 왜 굳이 번거롭게 combobox를 쓰는지 궁금할 수 있다.

 - 여러가지 이유가 있겠지만 가장 큰 이유는 Entry는 텍스트라는 제한 사항은 있지만

   우리가 원하지 않는 형태의 입력이 들어 올 수도 있기 때문인데,

   예를 들어 누군가 Entry에 '만3세' 라고 입력을 한다거나, '열세살', '중1' 등과 같은 예상치 못한 입력을 대응하기 어렵다.

   대응하기 어렵다는 의미는 에러 처리가 되거나 예상과 다른 예외처리가 되어야 한다는 의미인데,

   combobox를 사용하면 이런 예외 부분을 Entry보다 감소 시킬 수 있다.

 

 - 물론 위의 코드대로 combobox를 작성했다면 아직까지는 entry처럼 사용자가 직접 입력이 가능하다.

 - 이런 경우를 피하고 싶다면, 한가지 옵션을 더 추가해주면된다.

 - 50라인에서와 같이 combobox를 선언할 때, state='readonly' 파라미터를 추가하면 해당 요소에 직접 입력이 불가하고,

   우리가 지정한 리스트에 의한 입력만 가능하다.

 

 - 해당 상태의 변경과 선택된 나이를 출력하는 메서드를 추가한 코드를 작성하면 아래와 같다.

from tkinter import *
import tkinter.ttk

root = Tk()
root.title('To올라운드의 알찬 GUI 강의')

root.geometry("300x500") # 가로 X 세로 / 대문자X 하면 실행안됨

#msb.showinfo('Welcome','안녕하세요. To올라운더와 함께 하는 GUI입니다.')

def get_combobox_value():
    print(age1_input_combobox.get())


body_frame = Frame(root, relief='solid', bd=2, background='orange', padx=5, pady=5)
body_frame.pack(fill='both', expand=True)


# age_group_frame = Frame(body_frame, relief='solid', bd=2, background='orange', padx=5, pady=5)
# age_group_frame.pack()

# age_group_label = Label(age_group_frame, text='* 연령 그룹 선택')
# age_group_label.pack()

age_group_labelframe = LabelFrame(body_frame, text='연령 그룹 선택', relief='solid', bd=2, background='orange', padx=5, pady=5)
age_group_labelframe.pack()

age_group_value = IntVar()

age_group1 = Radiobutton(age_group_labelframe, text='미취학 아동(8세 미만)', value=1, variable=age_group_value)
age_group1.pack(anchor='nw')

age_group2 = Radiobutton(age_group_labelframe, text='초등학생(8 ~ 13세)', value=2, variable=age_group_value)
age_group2.pack(anchor='nw')

age_group3 = Radiobutton(age_group_labelframe, text='청소년(14 ~ 19세)', value=3, variable=age_group_value)
age_group3.pack(anchor='nw')

age_group4 = Radiobutton(age_group_labelframe, text='성인(20세 이상)', value=4, variable=age_group_value)
age_group4.pack(anchor='nw')

age_group_value.set(value=4) # radiobutton 기본 값 설정




age1_label = Label(body_frame, text='나이 : ')
age1_label.pack()

age1_list = [str(age)+'세' for age in range(1,120)]

age1_input_combobox = tkinter.ttk.Combobox(body_frame, height=3, values=age1_list, state='readonly')
age1_input_combobox.pack()

age1_input_combobox.set('나이를 선택하세요.')


get_combobox_value_btn = Button(body_frame, text ='Combobox 선택 항목 출력', command=get_combobox_value)
get_combobox_value_btn.pack(fill='x')


quit_btn = Button(body_frame, text='종료', command=quit)
quit_btn.pack(fill='x')


root.resizable(False,False) # x너비, y 변경 허용 여부
root.mainloop()

 

 

반응형