goodthings4me.tistory.com
파이썬 Tkinter는 파이썬으로 gui 프로그램을 만들 수 있도록 여러 컨테이너를 제공하는 라이브러리로 이를 배워두면 PC에서 실행할 수 있는 여러 응용 프로그램을 만들 수 있다. 그리고 tkinter는 button위젯, text위젯, frame위젯 등 모든 것이 위젯으로 구성되었다.
파이썬 Tkinter 모듈 따라 하면서 배우기
■ Label() 위젯
☞ tkinter 모듈의 Tk() 호출
☞ pakc() : 윈도우 스크린에 보이게 하기
☞ 아래로 위젯 배치
▣ 그리드 활용
☞ grid(row= , colume= ) 사용 시
■ Button() 위젯
☞ btn2 위젯은 DISABLED 시킴
☞ 버튼 사이즈 변경 - padx, pady
☞ fg=color, bg=color, command=함수 호출 → "Click" 버튼 누를 때마다 Label 위젯을 호출해 표시
- fg(foreground color), bg(background color) → RGB 색상코드도 입력 가능
■ Input Filed 관련 위젯 - Entry()
☞ 한 줄 입력하는 Entry 위젯
- 속성 : width, border, borderwidth, relief
- border의 relief는 solid, raised, ridge, groove, sunken, flat 중에서 선택할 수 있다.
☞ Button의 command=로 호출된 함수의 label1 위젯에서 Entry 위젯의 값을 text= 값으로 사용함
■ 계산기 만들어보기
from tkinter import *
root = Tk()
root.title('간단한 계산기')
# root.geometry('300x400+800+100')
entry = Entry(root, width=40, borderwidth=5)
entry.grid(row=0, column=0, columnspan=5, padx=10, pady=10)
def btn_click(number):
current = entry.get() # 입력값 얻기
entry.delete(0, END) # 입력값 지우기
entry.insert(0, str(current) + str(number)) # 얻은 입력값에 새로운 값 붙이기
return
def content_clear():
entry.delete(0, END)
def content_add():
first_number = entry.get()
global f_num
global math
math = 'add'
f_num = int(first_number)
entry.delete(0, END)
def content_sub():
first_number = entry.get()
global f_num
global math
math = 'sub'
f_num = int(first_number)
entry.delete(0, END)
def content_mul():
first_number = entry.get()
global f_num
global math
math = 'mul'
f_num = int(first_number)
entry.delete(0, END)
def content_div():
first_number = entry.get()
global f_num
global math
math = 'div'
f_num = int(first_number)
entry.delete(0, END)
def contetn_equal():
second_number = entry.get()
entry.delete(0, END)
if math == 'add':
entry.insert(0, f_num + int(second_number))
if math == 'sub':
entry.insert(0, f_num - int(second_number))
if math == 'mul':
entry.insert(0, f_num * int(second_number))
if math == 'div':
entry.insert(0, f_num / int(second_number))
button1 = Button(root, text='1', padx=30, pady=20, command=lambda: btn_click(1))
button2 = Button(root, text='2', padx=30, pady=20, command=lambda: btn_click(2))
button3 = Button(root, text='3', padx=30, pady=20, command=lambda: btn_click(3))
button4 = Button(root, text='4', padx=30, pady=20, command=lambda: btn_click(4))
button5 = Button(root, text='5', padx=30, pady=20, command=lambda: btn_click(5))
button6 = Button(root, text='6', padx=30, pady=20, command=lambda: btn_click(6))
button7 = Button(root, text='7', padx=30, pady=20, command=lambda: btn_click(7))
button8 = Button(root, text='8', padx=30, pady=20, command=lambda: btn_click(8))
button9 = Button(root, text='9', padx=30, pady=20, command=lambda: btn_click(9))
button0 = Button(root, text='0', padx=30, pady=20, command=lambda: btn_click(0))
btn_add = Button(root, text='+', padx=30, pady=20, command=content_add)
btn_sub = Button(root, text='-', padx=30, pady=20, command=content_sub)
btn_mul = Button(root, text='x', padx=30, pady=20, command=content_mul)
btn_div = Button(root, text='÷', padx=30, pady=20, command=content_div)
btn_equal = Button(root, text='=', padx=30, pady=20, command=contetn_equal)
btn_clear = Button(root, text='C', padx=30, pady=20, command=content_clear)
button1.grid(row=1, column=0)
button2.grid(row=1, column=1)
button3.grid(row=1, column=2)
btn_add.grid(row=1, column=3)
button4.grid(row=2, column=0)
button5.grid(row=2, column=1)
button6.grid(row=2, column=2)
btn_sub.grid(row=2, column=3)
button7.grid(row=3, column=0)
button8.grid(row=3, column=1)
button9.grid(row=3, column=2)
btn_mul.grid(row=3, column=3)
button0.grid(row=4, column=0)
btn_clear.grid(row=4, column=1)
btn_equal.grid(row=4, column=2)
btn_div.grid(row=4, column=3)
mainloop()
■ Tkinter Icon 붙이기, 이미지 뷰어 만들기
# pillow 모듈 설치 : pip install pillow
# PIL(pillow) 모듈 import : from PIL import ImageTk, Image
☞ 아이콘이나 이미지를 불러와서 Tkinter 창에 표시하기
- tkinter icon 변경 : root.iconbitmap()
- 버튼 클릭 시 창 닫히게 하기 : command=root.quit
- 이미지를 불러와서 Tkinter 창에 표시 : ImageTk.PhotoImage()와 Image.open() 활용
▣ 기능 확장해보기
- 이미지 넘기기(forward, back), 이미지수 표시
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
root.title('Tkinter 연습')
root.iconbitmap('./image/ico/g4m.ico')
image1 = ImageTk.PhotoImage(Image.open('./image/imagetk/output/image_01.jpg'))
image2 = ImageTk.PhotoImage(Image.open('./image/imagetk/output/image_02.jpg'))
image3 = ImageTk.PhotoImage(Image.open('./image/imagetk/output/image_03.jpg'))
image4 = ImageTk.PhotoImage(Image.open('./image/imagetk/output/image_04.jpg'))
image5 = ImageTk.PhotoImage(Image.open('./image/imagetk/output/image_05.jpg'))
img_lst = [image1, image2, image3, image4, image5]
status = Label(root, text=f'Image 1 of {str(len(img_lst))}', bd=1, relief=SUNKEN, anchor=E) # anchor=E 우측으로
status.grid(row=2, column=0, columnspan=3, pady=5, padx=5, sticky=W+E) # sticky= 좌우로 늘리기
label1 = Label(image=image1) # 1번째 이미지 셋팅
label1.grid(row=0, column=0, columnspan=3, padx=5, pady=5)
def forward(img_num):
global label1
global btn_forward
global btn_back
label1.grid_forget() # grid() 사라짐
label1 = Label(image=img_lst[img_num - 1])
btn_forward = Button(root, text='>>', command=lambda: forward(img_num + 1))
btn_back = Button(root, text='<<', command=lambda: back(img_num - 1))
if img_num == len(img_lst): # 이미지 수 체크해 비활성화
btn_forward = Button(root, text='>>', state=DISABLED)
label1.grid(row=0, column=0, columnspan=3)
btn_back.grid(row=1, column=0, pady=5)
btn_forward.grid(row=1, column=1)
status = Label(root, text=f'Image {img_num} of {str(len(img_lst))}', bd=1, relief=SUNKEN, anchor=E) # anchor=E 우측으로
status.grid(row=2, column=0, columnspan=3, pady=5, padx=5, sticky=W+E) # sticky= 좌우로 늘리기
def back(img_num):
global label1
global btn_forward
global btn_back
label1.grid_forget() # grid() 사라짐
label1 = Label(image=img_lst[img_num - 1])
btn_forward = Button(root, text='>>', command=lambda: forward(img_num + 1))
btn_back = Button(root, text='<<', command=lambda: back(img_num - 1))
if img_num == 1:
btn_back = Button(root, text='>>', state=DISABLED)
label1.grid(row=0, column=0, columnspan=3)
btn_back.grid(row=1, column=0, pady=5)
btn_forward.grid(row=1, column=1)
status = Label(root, text=f'Image {str(img_num)} of {str(len(img_lst))}', bd=1, relief=SUNKEN, anchor=E) # anchor=E 우측으로
status.grid(row=2, column=0, columnspan=3, pady=5, padx=5, sticky=W+E) # sticky= 좌우로 늘리기
# btn_back = Button(root, text='<<', command=back, state=DISABLED)
btn_back = Button(root, text='<<', state=DISABLED)
btn_back.grid(row=1, column=0, pady=5)
btn_forward = Button(root, text='>>', command=lambda: forward(2)) # 클릭 시 2번째부터
btn_forward.grid(row=1, column=1)
btn_quit = Button(root, text='닫기', command=root.quit)
btn_quit.grid(row=1, column=2)
mainloop()
■ LabelFrame
■ Radiobutton
☞ 레디오버튼 선택 시 Label에 값 표시
☞ 값을 선택하고 버튼 클릭 시 Label에 값 표시
■ 메시지 박스
☞ 메시지 박스 종류
shomwinfo, showwarning, showerror, askquestion, askokcancel, askyesno
■ 새 창 만들기
☞ Toplebel()로 새창을 만들고 Tk()와 동일한 방법으로 사용 가능
☞ 버튼을 만들어서 새창을 호출하고 닫기 (top.destroy)
■ 파일 가져오기 - 다이알로그 박스
# filedialog 모듈 추가
from tkinter import filedialog
from tkinter import *
from PIL import ImageTk, Image
from tkinter import filedialog
root = Tk()
root.title('Tkinter 연습')
root.geometry('300x350+800+100')
# filedialog.askopenfilename : 파일 오픈이 아닌 파일의 위치와 파일명을 리턴해줌
root.filename = filedialog.askopenfilename(initialdir='./image/imagetk/output', title='파일선택',
filetypes=(('jpg files', '*.jpg'), ('png files', '*.png'), ('all files', '*.*')))
label1 = Label(root, text=root.filename).pack()
image = ImageTk.PhotoImage(Image.open(root.filename)) # 파일위치와 파일명
img_label = Label(image=image).pack()
mainloop()
# filedialog.askopenfilename(initialdir='./image/imagetk/output', title='파일선택', filetypes=(('jpg files', '*.jpg'), ('png files', '*.png'), ('all files', '*.*')))
▣ 버튼 클릭 시 이미지 파일을 가져와서 보여주도록 함수로 처리
■ 슬라이더
# Scale()
▣ 수평 슬라이더에 따라 창 크기 변경
from tkinter import *
root = Tk()
root.title('Tkinter 연습')
root.geometry('250x200+800+100')
vertical = Scale(root, from_=0, to=200)
vertical.pack()
horizontal = Scale(root, from_=0, to=400, orient=HORIZONTAL)
horizontal.pack()
def slide():
label1 = Label(root, text=horizontal.get()).pack()
root.geometry(str(horizontal.get()) + 'x400+800+100')
btn1 = Button(root, text='Click', command=slide).pack()
mainloop()
■ 체크박스(버튼)
# Checkbutton
# 체크되면 1, 안되면 0
# 문자(열)인 경우 onvalue=, offvalue= 에 값 설정 후 실행시킬 수 있음
■ 드롭박스(옵션 메뉴)
# OptionMenu()
☞ 메뉴 클릭 시 리스트가 보임
☞ 기능
- options 변수 만들고 요일 리스트 할당,
- 초기값으로 index 0번 설정,
- options 리스트는 가변 매개변수 *options로,
- show() 함수로 Label() 만들어서 선택된 값을 출력
■ Tkinter에서 데이터베이스 사용하는 방법
from tkinter import *
import sqlite3
root = Tk()
root.title('Tkinter 연습')
# database 생성 및 연결
conn = sqlite3.connect('address.db')
cursor = conn.cursor() # 커서 생성
# # table 생성 - 생성되면 주석 처리함
# cursor.execute('''create table addresstb (
# name text,
# tel text,
# address text
# )''')
name_label = Label(root, text='이름')
name_label.grid(row=0, column=0)
name = Entry(root, width=10)
name.grid(row=0, column=1, padx=20, pady=5)
tel_label = Label(root, text='전화번호')
tel_label.grid(row=1, column=0)
tel = Entry(root, width=20)
tel.grid(row=1, column=1, padx=20, pady=5)
address_label = Label(root, text='주소')
address_label.grid(row=2, column=0)
address = Entry(root, width=30)
address.grid(row=2, column=1, padx=20, pady=5)
submit_btn = Button(root, text='저장', command='submit')
submit_btn.grid(row=3, column=0, columnspan=2, padx=10, pady=10, ipadx=30)
conn.commit()
conn.close()
mainloop()
▣ CRUD 해보기
from tkinter import *
import sqlite3
root = Tk()
root.title('Tkinter 연습')
# # database 생성 및 연결
# conn = sqlite3.connect('address.db')
# cur = conn.cursor() # 커서 생성
#
# # table 생성 - 생성되면 주석 처리함
# cur.execute('''create table addresstb (
# name text,
# tel text,
# address text
# )''')
#
# conn.commit()
# conn.close()
def submit():
conn = sqlite3.connect('address.db')
cur = conn.cursor() # 커서 생성
# 데이터 입력
cur.execute('insert into addresstb values(:name, :tel, :address)', {
'name': name.get(),
'tel': tel.get(),
'address': address.get()
})
conn.commit()
conn.close()
name.delete(0, END) # 입력값 지우기
tel.delete(0, END)
address.delete(0, END)
def select_query():
conn = sqlite3.connect('address.db')
cur = conn.cursor()
# 데이터 조회
cur.execute('select *, oid from addresstb')
rs = cur.fetchall()
print(rs)
records = ''
for record in rs: # rs[0]: # rs[0]는 맨 처음 값 1개
records += str(record) + '\n'
# for record in rs: # 구분자를 넣어서 문자열로 관리
# records += record[0] + '/' + record[1] + '/' + record[2] + '\n'
q_label = Label(root, text=records)
q_label.grid(row=5, column=0, columnspan=3)
conn.commit()
conn.close()
name.delete(0, END)
tel.delete(0, END)
address.delete(0, END)
def delete_query():
conn = sqlite3.connect('address.db')
cur = conn.cursor()
# 데이터 삭제
cur.execute('delete from addresstb where oid = ' + delete_entry.get())
print('삭제!!')
del_label = Label(root, text='oid ' + delete_entry.get() + ' 삭제 완료!')
del_label.grid(row=8, column=0, columnspan=3)
conn.commit()
conn.close()
name.delete(0, END)
tel.delete(0, END)
address.delete(0, END)
def update():
conn = sqlite3.connect('address.db')
cur = conn.cursor()
record_id = delete_entry.get()
# 데이터 업데이트
cur.execute('UPDATE addresstb SET name=:name, tel=:tel, address=:address WHERE oid=:oid', {
'name': edit_name.get(),
'tel': edit_tel.get(),
'address': edit_address.get(),
'oid': record_id
})
print('수정 완료!!')
result_update_label = Label(root, text='oid ' + delete_entry.get() + ' 수정 완료!')
result_update_label.grid(row=10, column=0, columnspan=3)
conn.commit()
conn.close()
delete_entry.delete(0, END)
editor.destroy()
def edit():
global editor
editor = Tk() # 새창 만들어서 업데이트 진행
editor.title('Update Records')
conn = sqlite3.connect('address.db')
cur = conn.cursor() # 커서 생성
record_id = delete_entry.get()
cur.execute('select * from addresstb where oid=' + record_id)
rs = cur.fetchall()
print(rs)
conn.commit()
conn.close()
global edit_name
global edit_tel
global edit_address
edit_name_label = Label(editor, text='이름')
edit_name_label.grid(row=0, column=0)
edit_name = Entry(editor, width=30)
edit_name.grid(row=0, column=1, padx=20, pady=5)
edit_tel_label = Label(editor, text='전화번호')
edit_tel_label.grid(row=1, column=0)
edit_tel = Entry(editor, width=30)
edit_tel.grid(row=1, column=1, padx=20, pady=5)
edit_address_label = Label(editor, text='주소')
edit_address_label.grid(row=2, column=0)
edit_address = Entry(editor, width=30)
edit_address.grid(row=2, column=1, padx=20, pady=5)
edit_save_btn = Button(editor, text='수정하기', command=update)
edit_save_btn.grid(row=3, column=0, columnspan=3, padx=10, pady=10, ipadx=30)
for record in rs:
edit_name.insert(0, record[0])
edit_tel.insert(0, record[1])
edit_address.insert(0, record[2])
name_label = Label(root, text='이름')
name_label.grid(row=0, column=0)
name = Entry(root, width=30)
name.grid(row=0, column=1, padx=20, pady=5)
tel_label = Label(root, text='전화번호')
tel_label.grid(row=1, column=0)
tel = Entry(root, width=30)
tel.grid(row=1, column=1, padx=20, pady=5)
address_label = Label(root, text='주소')
address_label.grid(row=2, column=0)
address = Entry(root, width=30)
address.grid(row=2, column=1, padx=20, pady=5)
delete_label = Label(root, text='선택 ID')
delete_label.grid(row=6, column=0, pady=5)
delete_entry = Entry(root, width=30)
delete_entry.grid(row=6, column=1, pady=5)
submit_btn = Button(root, text='저장', command=submit)
submit_btn.grid(row=3, column=0, columnspan=2, padx=10, pady=10, ipadx=53)
q_select_btn = Button(root, text='Select Record', command=select_query)
q_select_btn.grid(row=4, column=0, columnspan=3, padx=10, pady=10, ipadx=30)
q_del_btn = Button(root, text='Delete Record', command=delete_query)
q_del_btn.grid(row=7, column=0, columnspan=3, padx=10, pady=10, ipadx=30)
q_update_btn = Button(root, text='Update Record', command=edit)
q_update_btn.grid(row=9, column=0, columnspan=3, padx=10, pady=10, ipadx=30)
mainloop()
※ [출처] Tkinter Course - Create Graphic User Interfaces in Python Tutorial
tkinter 예제 따라하면서 배워보기>>
'코딩 연습 > 코딩배우기' 카테고리의 다른 글
파이썬 pip 명령 에러 메시지 - ModuleNotFoundError: No module named 'pip' (0) | 2021.12.12 |
---|---|
파일명 일괄 변경하기 (with 파이썬) (0) | 2021.12.06 |
파이썬 qrcode, tkinter 모듈로 만든 QR코드 생성기 (0) | 2021.11.21 |
네이버 블로그 페이지에 있는 글 저장 및 이미지 다운로드하는 기능 만들기(with 파이썬) (3) | 2021.11.12 |
파이썬 장고(django) 웹 프로그래밍 - 웹 페이지 만들기 # 2 (0) | 2021.11.03 |
댓글