반응형
* 기본적인 위젯 사용법은 알고 있다는 가정하에 작성하였습니다.
목적
button, label, entry를 사용자가 입력한 수만큼 생성한다.
시나리오
1. num에 임의의 수 n을 입력 후 make버튼을 선택
2. 레이블, 엔트리, 버튼이 n개만큼 생성
3. button을 선택 시 해당 label에 입력된 값과 같은 값 출력
구현
위젯을 동적생성하는것에 초점을 맞추어 설명한다.
make 버튼에 동적생성함수 연결
make버튼에 위젯들을 동적생성하는 MakeDynamicWidget함수를 command 파라미터로 연결한다.
MakeDynamicWidget 파라미터(entry_input.get())는 엔트리에서 읽은 값이다.
...
btn_open_input = tkinter.Button(frame_input, width=10, text="make", command=lambda:MakeDynamicWidget(entry_input.get()))
...
MakeDynamicWidget 함수 구현
우선 위젯들을 담을 리스트를 만든다.(2~4라인)
그리고 for문을 이용하여 entry_input.get()로 읽은 값(num)만큼 위젯 리스트에 위젯을 삽입(append)하고 그려준다.
버튼, 엔트리에는 for문의 인덱스를 파라미터로 사용한다. 이 파라미터가 어떤 버튼이 선택되었는지 구별하는 인덱스가 된다.
# 생성할 위젯들
entries = []
labels = []
buttons = []
def MakeDynamicWidget(num):
num = int(num)
for i in range(num):
labels.append(tkinter.Label(frame_result, text=i, padx=10))
labels[i].grid(row=i, column=0)
entries.append(tkinter.Entry(frame_result, width=10))
entries[i].grid(row=i, column=1)
buttons.append(tkinter.Button(frame_result, width=10, text="button", command=lambda i=i: Buttonselect(i)))
buttons[i].grid(row=i, column=2)
Buttonselect 함수 구현
Buttonselect함수는 button을 선택하면 entry에 값이 입력되는 함수다.
해당 코드는 Buttonselect함수의 파라미터를 이용, 선택한 버튼과 동일한 엔트리를 찾고 인덱스값을 입력해준다.
def Buttonselect(idx):
entries[idx].delete(0, 'end')
entries[idx].insert(0, idx)
전체코드
구조화 전과 후로 코드를 나누었다.
두개는 동일한 코드이며 객체지향으로 재구성한것이 구조화 후이다.
구조화 전
import tkinter
entries = []
labels = []
buttons = []
def MakeDynamicWidget(num):
num = int(num)
for i in range(num):
labels.append(tkinter.Label(frame_result, text=i, padx=10))
labels[i].grid(row=i, column=0)
entries.append(tkinter.Entry(frame_result, width=10))
entries[i].grid(row=i, column=1)
buttons.append(tkinter.Button(frame_result, width=10, text="button", command=lambda i=i: Buttonselect(i)))
buttons[i].grid(row=i, column=2)
def Buttonselect(idx):
entries[idx].delete(0, 'end')
entries[idx].insert(0, idx)
main_window = tkinter.Tk()
main_window.title('test')
main_window.geometry('200x200+0+0') # windows size : width, heigth, x, y
main_window.resizable(False, False) # window scale enable : Updown, LeftRight
frame_input = tkinter.Frame(main_window)
frame_result = tkinter.Frame(main_window)
frame_input.grid(row=0, column=0)
frame_result.grid(row=1, column=0)
lbl_input = tkinter.Label(frame_input, text="num", padx=10)
entry_input = tkinter.Entry(frame_input, width=10)
btn_input = tkinter.Button(frame_input, width=10, text="make", command=lambda:MakeDynamicWidget(entry_input.get()))
lbl_input.grid(row=0, column=0)
entry_input.grid(row=0, column=1)
btn_input.grid(row=0, column=2)
main_window.mainloop()
구조화 후
import tkinter
class DynamicWidget:
def __init__(self, mainFrame):
self.entries = []
self.labels = []
self.buttons = []
self.frame_input = tkinter.Frame(mainFrame)
self.frame_result = tkinter.Frame(mainFrame)
self.frame_input.grid(row=0, column=0)
self.frame_result.grid(row=1, column=0)
lbl_input = tkinter.Label(self.frame_input, text="num", padx=10)
entry_input = tkinter.Entry(self.frame_input, width=10)
btn_input = tkinter.Button(self.frame_input, width=10, text="make", command=lambda:DynamicWidget.MakeDynamicWidget(self, entry_input.get()))
lbl_input.grid(row=0, column=0)
entry_input.grid(row=0, column=1)
btn_input.grid(row=0, column=2)
def MakeDynamicWidget(self, num):
num = int(num)
for i in range(num):
self.labels.append(tkinter.Label(self.frame_result, text=i, padx=10))
self.labels[i].grid(row=i, column=0)
self.entries.append(tkinter.Entry(self.frame_result, width=10))
self.entries[i].grid(row=i, column=1)
self.buttons.append(tkinter.Button(self.frame_result, width=10, text="button", command=lambda i=i: DynamicWidget.Buttonselect(self, i)))
self.buttons[i].grid(row=i, column=2)
def Buttonselect(self, idx):
self.entries[idx].delete(0, 'end')
self.entries[idx].insert(0, idx)
def main():
main_window = tkinter.Tk()
main_window.title('test')
main_window.geometry('200x200+0+0') # windows size : width, heigth, x, y
main_window.resizable(False, False) # window scale enable : Updown, LeftRight
dynamicWidget = DynamicWidget(main_window)
main_window.mainloop()
if __name__ == '__main__':
main()
최근댓글