GUI란 뭔가요?
그래픽 사용자 인터페이스(Graphical User Interface)의 약자입니다.
컴퓨터와 사용자 간의 상호 작용을 위해 그래픽 요소를 사용하는 인터페이스를 말합니다.
GUI는 텍스트 기반 인터페이스보다 사용하기 쉽고 직관적입니다.
또한, GUI는 다양한 그래픽 요소를 사용하여 사용자의 관심을 끌고 사용자의 경험을 향상시킬 수 있습니다.
GUI 코딩을 하려면 어떻게 해야 하나요?
Tkinter 라이브러리를 사용해야 합니다.
Tkinter는 파이썬과 함께 제공되는 표준 GUI 라이브러리입니다.
Tkinter를 사용하면 간단한 GUI를 쉽게 만들 수 있습니다.
Hello라는 글자를 창에 보이게 하려면 어떻게 해야 하나요?
Tkinter 라이브러리를 불러옵니다.
글자 크기를 설정하기 위해 tkinter.font 라이브러리도 불러옵니다.
tkinter.Tk() 함수로 윈도우 개체를 생성합니다.
title("hello") 함수로 창의 제목을 hello로 정합니다.
geometry(“600x300") 함수로 창의 가로와 세로 크기를 지정해 줍니다. 곱하기 x는 영어 소문자입니다.
Font(size = 30) 함수로 글자크기를 30으로 설정합니다.
Label(window, text=“반갑다, 파이썬~", font=font) 함수로 창에 글자를 출력합니다. 여기서 window 변수는 윈도우 개체이며, font 변수는 글자 크기를 30으로 정한 변수입니다.
pack() 함수로 label 위젯을 창(컨테이너)에 배치합니다.
mainloop() 함수로 이벤트 루프를 시작하고, 애플리케이션이 종료될 때까지 계속 실행합니다. 이벤트 루프는 사용자의 입력, 마우스 클릭, 키보드 입력 등과 같은 이벤트를 처리합니다.
Hello 글자 출력 창 코딩
import tkinter
import tkinter.font # 폰트 라이브러리 불러옴
window = tkinter.Tk() # 윈도우 개체 생성
window.title(“파이썬 코딩")
window.geometry(“600x300") # x는 영어 소문자
font = tkinter.font.Font(size = 30) # 글자크기 설정
label=tkinter.Label(window, text="반갑다, 파이썬~", font=font) # 문자 출력
label.pack()
window.mainloop() # 윈도우를 계속 유지시킴
간단한 시계를 만들려면 어떻게 해야 하나요?
1초마다 실행되는 함수를 만듭니다.
함수 안에 mySec 전역 변수를 사용하기 위해 global로 mySec을 전역 변수로 선언합니다.
mySec에 1을 더하고 이를 label의 text로 지정합니다.
1초 후에 함수를 다시 실행합니다. 자기 자신을 다시 실행하는 재귀함수입니다.
같은 방식으로 1분마다 실행되는 함수도 만듭니다.
윈도우가 실행되면 함수도 실행되도록 합니다.
1초마다 숫자 증가하는 함수 코딩
mySec = 0
def get_sec():
global mySec
# 함수 밖에 있는 변수를 사용하고자 전역 변수로 선언
nowNum = str(mySec)
mySec = mySec + 1
label.config(text= nowNum) # 라벨의 text에 cnt 값을 지정
window.after(1000,get_sec) # 1초 후에 재귀함수 실행
get_1sec()
간단한 시계 코딩
import tkinter
import tkinter.font
window = tkinter.Tk()
window.geometry("100x100+1110+840")
window.wm_attributes("-topmost", True) # 창 맨 위에
font = tkinter.font.Font(size = 30)
label=tkinter.Label(window, font=font)
label.pack()
label2=tkinter.Label(window, font=font)
label2.pack()
mySec = 0
myMin = 0
def get_sec():
global mySec
nowNum = str(mySec)
mySec = mySec + 1
label.config(text=nowNum)
window.after(1000,get_sec)
if mySec == 60 :
mySec = 0
def get_min():
global myMin
nowNum = str(myMin)
myMin = myMin + 1
label2.config(text=nowNum)
window.after(60000,get_min)
get_sec()
get_min()
window.mainloop()
실시간 뉴스를 업데이트 하는 GUI 코딩을 하려면 어떻게 해야 하나요?
기존 GUI 코딩에다 웹 크롤링에서 실시간 뉴스를 가져오는 코딩을 편집합니다.
실시간 뉴스를 가져와 출력하는 위젯으로 Text를 사용합니다. wrap=‘word’로 자동 줄바꿈을 단어 기준으로 하고, font=("Arial", 20, 'bold')로 글꼴과 글자 크기를 정합니다.
실시간 뉴스를 업데이트 하는 단추에 실시간 뉴스 크롤링 하는 함수를 연결(매핑)합니다.
실시간 뉴스 업데이트 GUI 코딩
import tkinter as tk
import requests
from bs4 import BeautifulSoup
# tkinter 창 생성
window = tk.Tk()
window.title("실시간 뉴스")
# 뉴스 목록 레이블 생성
news_label = tk.Label(window, text="실시간 뉴스")
news_label.pack()
# 뉴스 목록 텍스트박스 생성
news_textbox = tk.Text(master=window, wrap='word', font=("Arial", 20, 'bold'))
news_textbox.pack()
def crawl_news(): # 뉴스 크롤링 함수
# 구글 뉴스 URL 가져오기
url = " https://news.google.com/home?hl=ko&gl=KR&ceid=KR:ko "
response = requests.get(url) # 구글 뉴스 페이지 요청
# 구글 뉴스 페이지를 BeautifulSoup으로 파싱
soup = BeautifulSoup(response.content, "html.parser")
# 뉴스 목록 가져오기
news_list = soup.find_all("div", class_='KDoq1')
# 뉴스 목록을 텍스트박스에 추가하기
for news in news_list:
news_textbox.insert('end', news.find("div").text)
news_textbox.insert('end', '\n') # 줄바꾸기
# 뉴스 목록을 갱신하는 함수
def update_news():
news_textbox.delete(1.0,'end') # 1행.0열부터 끝까지 삭제
crawl_news() # 뉴스 크롤링 함수 호출
# 뉴스 목록을 갱신하는 버튼 생성
update_button = tk.Button(window, text="Update", command=update_news)
update_button.pack()
update_news() # 창이 실행되면서 먼저 뉴스 크롤링
window.mainloop() # tkinter 창 실행
메모장 같은 문서 편집 프로그램을 만글려면 어떻게 해야 하나요?
우선 텍스트 박스, 스크롤바, 메뉴 등을 만듭니다.
파일 메뉴에 새로 만들기, 열기, 저장, 다른 이름으로 저장, 종료 등의 메뉴를 만듭니다.
도움말 메뉴에 메모장 정보 메뉴를 만듭니다.
각 메뉴에서 실행할 함수를 작성합니다.
스크롤바를 어떻게 만드나요?
세로 스크롤바를 창 오른쪽에 배치시킵니다.
scrollbar = Scrollbar(window)
scrollbar.pack(side=RIGHT, fill=Y)
텍스트박스에 세로 스크롤바로 앞에 만들어 놓은 스크롤바를 지정합니다.
textBox = Text(master=window, wrap='word', yscrollcommand=scrollbar.set)
스크롤바와 텍스트상자를 연결해 줍니다.
scrollbar.config(command=textBox.yview)
메모장 코딩 1
from tkinter import *
from tkinter.filedialog import *
def new_file():
pass
def open_file():
pass
def save_as_file():
pass
def save_file():
pass
def maker():
pass
window = Tk()
window.title("메모장")
window.geometry("800x600")
scrollbar = Scrollbar(window)
scrollbar.pack(side=RIGHT, fill=Y)
메뉴를 어떻게 만드나요?
Menu(window) 함수로 메뉴 위젯을 만듭니다. 여기서 window는 tkinter.Tk(), 즉 창을 매개변수로 넣어주어야 합니다. Window가 master인 셈입니다.
다음으로 상위 메뉴를 추가합니다. 앞에 만든 메뉴 위젯을 master로 하고 분리시킬 수 없도록 합니다.
myMenu = Menu(window)
fileMenu = Menu(myMenu, tearoff=0)
메뉴 위젯에 상위 메뉴에 대한 설정을 해줍니다. 상위 메뉴 이름 라벨를 ‘파일’로 하고, 만들어 둔 상위 메뉴 변수명을 메뉴 옵션에 연결시킵니다.
myMenu.add_cascade(label="파일", menu=fileMenu)
하위 메뉴를 추가합니다. 메뉴 라벨을 ‘새파일’로 하고, 이를 실행할 함수 이름을 command 옵션에 지정해 줍니다.
fileMenu.add_command(label="새파일", command=new_file)
필요하면 분리선을 넣어줍니다.
fileMenu.add_separator()
창의 환경 설정으로 메뉴 옵션에 만들어 놓은 메뉴 위젯을 연결합니다.
window.config(menu=myMenu)
메모장 코딩 2
myMenu = Menu(window)
fileMenu = Menu(myMenu, tearoff=0)
myMenu.add_cascade(label="파일", menu=fileMenu)
fileMenu.add_command(label="새파일", command=new_file)
fileMenu.add_command(label="열기", command=open_file)
fileMenu.add_command(label="저장", command=save_file)
fileMenu.add_command(label="다른 이름으로 저장", command=save_as_file)
fileMenu.add_separator()
fileMenu.add_command(label="종료", command=window.destroy)
helpMenu = Menu(myMenu, tearoff=0)
myMenu.add_cascade(label="도움말", menu=helpMenu)
helpMenu.add_command(label="메모장 정보", command = maker)
텍스트박스를 어떻게 만드나요?
Text(master, 옵션) 함수로 텍스트박스 위젯을 만듭니다. 자동 줄바꿈 옵션으로 단어(word) 기준으로 줄을 바꾸게 하고, 폰트 옵션으로 글꼴을 지정해 줍니다.
textBox = Text(master=window, wrap='word', font=("Arial", 20, 'bold'), yscrollcommand=scrollbar.set)
위젯을 창에 배치하면서 옵션(속성)으로 왼쪽에 배치하도록 하고, 창 너비와 높이를 모두 채우게 하고, 창의 크기를 확대할 때 같이 커지도록 합니다.
textBox.pack(side=LEFT, fill=BOTH, expand=True)
메모장 코딩 3
textBox = Text(master=window, wrap='word', font=("Arial", 20, 'bold'), yscrollcommand=scrollbar.set)
textBox.pack(side=LEFT, fill=BOTH, expand=True)
# 스크롤바와 텍스트상자 연결
scrollbar.config(command=textBox.yview) window.config(menu=myMenu) # 창에 메뉴 연결
window.mainloop()
새파일 함수를 어떻게 만드나요?
Delete 함수로 텍스트박스에 있는 모든 내용을 삭제합니다.
textBox.delete(1.0,END)
1.0?
첫번째 줄, 첫번째 열을 뜻합니다. 즉 ‘문서 제일 처음부터’를 의미합니다.
END는?
텍스트 위젯의 특수 키워드로서, 문제 제일 끝까지를 의미합니다. 문자열로 ‘end’를 사용해도 됩니다.
def new_file():
textBox.delete(1.0,END)
열기 함수를 어떻게 만드나요?
파일을 열 때도 우선 delete 함수로 텍스트박스에 있는 모든 내용을 삭제합니다.
textBox.delete(1.0,END)
Tkinter의 filedialog 라이브러리에 있는 askopenfilename 함수로 열기 대화상자를 띄웁니다. 이때 대화상자 제목을 ‘열기’로 정해줍니다. 이 대화상자에서 선택한 파일을 file_name 변수에 넣습니다.
file_name = askopenfilename(title="열기")
파일을 열 때 with as 구문(명령어)을 사용합니다. 그 이유는 읽어 들인 내용이 없어지지 않게 하고자 함인데, 안전하게 파일을 핸들링 하는 기법입니다.
파일을 open(파일이름, 모드) 함수를 통해 file_name 변수에 지정한 파일을 r 모드(읽기 모드)로 열어 객체로 만들어 변수 f에 넣습니다. 이렇게 안전하게 파일 내용을 유지한 상태에서 텍스트박스에 파일의 내용을 읽어 들여(read() 함수로) 텍스트박스 제일 첫 줄에 삽입합니다.
with open(file_name, "r") as f:
textBox.insert(1.0, f.read())
def open_file():
textBox.delete(1.0,END)
file_name = askopenfilename(title="열기")
with open(file_name, "r") as f:
textBox.insert(1.0, f.read())
저장 함수를 어떻게 만드나요?
파일을 열 때처럼, Tkinter의 filedialog 라이브러리에 있는 asksaveasfilename 함수로 ‘다른 이름으로 저장’ 대화상자를 띄웁니다. 이때 쓰기 모드로 하고, 기본 확장자를 ‘.txt’로 하며, filetypes 옵션으로 파일 형식과 확장자를 리스트에 튜플로 지정해 줍니다. filetypes 옵션은 대화상자의 파일 형식 목록단추에 표시됩니다. 이 대화상자에서 선택한 파일을 f 변수에 넣습니다.
f = asksaveasfile(mode = "w", defaultextension=".txt",filetypes=[('텍스트 파일', '.txt')])
파일 쓰기 함수인 write()에 텍스트박스의 처음부터 끝까지 모든 문자를 매개 변수로 넣어 저장합니다.
f.write(textBox.get(1.0, END)
def save_file():
f = asksaveasfile(mode = "w", defaultextension=".txt", filetypes=[(‘텍스트 파일', '.txt')])
f.write(textBox.get(1.0, END))
f.close()
다른 이름으로 저장 함수는 왜 필요한가요?
저장 함수만 사용하면 늘 ‘다른 이름으로 저장’ 대화상자가 나오고, 다시 파일 이름을 만들거나 기존의 파일에 덮어씌우기를 해야 하는 불편함이 있습니다.
그래서 기존의 저장 함수를 다른 이름으로 저장 함수로 바꾸고
새로운 저장 함수엔, 만약 파일 이름이 있다면, 즉 열기 함수로 파일을 가져와 이미 파일 이름이 있다면, 그 파일 이름으로 저장하도록 하고
그렇지 않다면, 즉 파일 이름이 없다면, 그러니까 열기 함수로 파일을 가져오지 않았다면, 다른 이름으로 저장 함수를 실행시킵니다.
이를 위해 별도로 변수(openStatusFile)를 만들어 처음 프로그램 실행 때 기본값으로 변수값을 False로 정해주고, 열기 함수를 실행하여 파일 이름을 가지게 되면 이 변수에 그 파일 이름을 지정해 주어 변수값이 True가 되게 하고 만약 변수가 True라면 그 이름으로 저장을 하고, 파일을 연 적이 없어 파일 이름이 없어 변수값이 기본값대로 False라면 다른 이름으로 저장 함수를 실행합니다.
먼저 코딩 상단에 전역 변수로 선언해 줍니다. 전역 변수는 함수 외부에, 그러니까 함수보다 먼저 그 위에 선언해 줍니다.
from tkinter.filedialog import *
openStatusFile = False
def new_file():
전역 변수를 함수에서 사용하려면 global 키워드를 사용해야 합니다.
def open_file():
textBox.delete(1.0,END)
file_name = askopenfilename(title="열기")
global openStatusFile
openStatusFile = file_name
위 코딩의 경우, 열기 함수에서 openStatusFile 변수를 global 키워드로 가져와 사용하였고, 이 변수에 file_name 변수를 지정하여 값을 True로 만들고,
이 openStatusFile 변수를 다시 저장 함수에서 사용하여 파일 이름이 있는 경우에는 다시 다른 이름으로 저장 함수가 실행되지 않고, 그냥 그 이름으로 저장하도록 합니다.
이를 위해 if 문을 사용합니다. if 문은 조건이 참일 때만 실행됩니다. 열기 함수로 가져온 파일이 아닐 경우엔 다른 이름으로 저장 함수가 실행되도록 else 키워드를 사용합니다.
def save_file():
global openStatusFile
if openStatusFile:
tf = open(openStatusFile, 'w')
tf.write(textBox.get(1.0, END))
tf.close()
else:
save_as_file()
메모장을 실행하고 그냥 저장한 경우엔 처음이라면 모르지만 왜 계속 다른 이름으로 저장 창이 뜨나요?
처음 다른 이름으로 저장할 때, openStatusFile 변수의 값을 바꾸어 주지 않았기 때문입니다. 이때 openStatusFile 변수의 값을 참(True)으로 해주면 저장 함수를 실행할 때 다른 이름으로 저장 대화상자를 띄우지 않고, 그 이름으로 그냥 저장해 줍니다.
전역 변수로 가져온 openStatusFile 변수에 현재 파일의 이름을 넣어주려면, f.name 함수(메서드)를 사용해야 합니다. f.write가 파일 객체 f에 문자열을 저장하듯이, f.name은 파일 객체 f의 이름을 가져옵니다.
다른 이름으로 저장 함수 코딩 수정
def save_as_file():
f = asksaveasfile(mode = "w", defaultextension=".txt",filetypes=[('텍스트 파일', '.txt')])
f.write(textBox.get(1.0, END))
global openStatusFile
openStatusFile = f.name # 파일 이름 가져오기
f.close()
열기를 한 후, 다시 새파일을 만들고 저장하면 왜 다른 이름으로 저장 창이 안 뜨나요?
열기 함수를 실행하면, openStatusFile 값이 참이므로, 새파일 함수를 실행하고 저장을 하면 그 값이 그대로 적용되어 다른 이름으로 저장하는 대화상자가 안 나타나고 그대로 기존 파일 이름으로 저장이 됩니다.
따라서 새파일 함수를 실행할 때 openStatusFile 값을 거짓으로 설정해 주어야 합니다.
def new_file():
textBox.delete(1.0,END)
global openStatusFile
openStatusFile = False
창 처음 열리고 커서가 텍스트박스에 나타나게 하려면 어떻게 하나요?
textBox.focus_set()
window.mainloop() 바로 위에다 적어줍니다.
이렇게 안 하면 텍스트박스를 한 번 클릭해야 커서 나타나고 그런 연후에 입력 가능합니다.
파일을 열었을 때, 문서의 제일 끝을 보여주도록 하려면 어떻게 하나요?
textBox.yview(END)
open_file() 함수 제일 아래에 적어줍니다.
만든이 함수는 어떻게 만드나요?
Toplevel(window) 위젯을 사용합니다. 이 위젯을 사용하면 새로운 창을 만들 수 있습니다. 부모(parent) 창으로 window를 지정한 것입니다.
창 크기와 위치를 정하고, 제목으로 ‘메모장 정보’를 지정해 주고, 창에 ‘Memo.01’이라고 Label 위젯으로 적어줍니다.
def maker():
help_view = Toplevel(window)
help_view.geometry("300x50+300+300")
help_view.title("메모장 정보")
lb = Label(help_view, text = "Memo.01")
lb.pack()
제목표시줄에 파일 이름을 표시하려면 어떻게 하나요?
제목표시줄에 제목을 표시하는 함수 window.title(문자)를 이용합니다.
우선 열기 함수에
window.title(file_name + ' - 메모장')
다른 이름으로 저장 함수에
window.title(f.name + ' - 메모장')
새파일 함수에
window.title('빈 문서 - 메모장')
저장하지 않고 그냥 종료를 할 경우 저장할지 묻는 창이 나오게 하려면 어떻게 하나요?
우선 필요한 메시지 창 라이브러리를 가져옵니다.
import tkinter.messagebox as msgbox
종료 함수를 만듭니다.
종료 메뉴와 창 닫기 단추를 눌렀을 때, 종료 함수가 실행되도록 연결(Binding)시켜 줍니다.
종료 함수를 만들려면 어떻게 하나요?
우선 텍스트 수정 여부 체크용으로 블린 변수를 만들고 기본값으로 False를 셋(설정)합니다.window.geometry("800x600") 아래에 다음과 같이 작성합니다.
text_modified = BooleanVar()
text_modified.set(False)
텍스트 상자에 자판을 사용하여 입력하게 되면, text_modified의 값을 True로 바꾸는 함수가 실행되도록 합니다.
textBox.pack(side=LEFT, fill=BOTH, expand=True)
아래에 다음과 같이 입력합니다.
textBox.bind("<Key>", on_text_modified)
"<Key>” 이벤트는 텍스트 상자에 자판으로 입력하는 이벤트를 말합니다.
on_text_modified 함수는 close_event 함수 아래에 다음과 같이 작성합니다.
def on_text_modified(event):
text_modified.set(True)
예 단추를 누르면 저장 함수가 실행되도록 하고, 아니오 단추를 누르면 그냥 창을 닫도록 합니다. 다음 슬라이드와 같이 코딩합니다.
def close_event():
if text_modified.get():
answer = msgbox.askquestion("저장했나요", "저장하길 원하나요?")
if answer == msgbox.YES:
save_file()
else:
window.destroy()
else:
window.destroy()
Get() 함수는 text_modified 변수의 블린 값을 가져오는 함수입니다.
종료 메뉴를 눌렀을 때, 종료 함수가 실행되도록 하려면 어떻게 하나요?
종료 함수(close_event)를 command 옵션으로 지정합니다.
fileMenu.add_command(label="종료", command=close_event)
창 닫기 단추를 눌렀을 때, 종료 함수가 실행되도록 하려면 어떻게 하나요?
종료 함수(close_event)를 메인 창의 닫기 단추에 연결(biding)하려면, protocol() 함수를 사용합니다. protocol() 함수는 창에 대한 프로토콜을 설정하는 데 사용됩니다. 프로토콜은 창에서 발생하는 이벤트를 처리하는 데 사용되는 규칙 세트입니다.Protocol(프로토콜 이름, 연결할 함수 이름)WM_DELETE_WINDOW는 Tkinter에서 창을 닫는 데 사용되는 프로토콜입니다.
window.protocol("WM_DELETE_WINDOW", close_event)
문서를 열거나 저장할 때 단추키를 사용하려면 어떻게 하나요?
bind() 함수를 사용하여 단축키를 설정합니다.
window.bind("<Control-o>", key_open_file)
window.bind("<Control-s>", key_save_file)
단축키와 연결한 함수 key_open_file와, key_save_file을 작성합니다.
def key_open_file(o):
if o:
open_file()
def key_save_file(s):
if s:
save_file()
기존에 있던 open_file 함수나 save_file 함수를 사용하지 않고, 왜 따로 key_open_file 함수와 key_save_file 함수를 만드나요?
bind() 함수에서 단축키로 사용하는 함수는 함수를 만들 때 매개변수를 넣어주어야 키값을 매개할 수 있기 때문입니다. 단축키를 눌렀다면(if s:) 저장하거나 열거나 할 수 있도록 코딩해주어야 합니다.
메뉴에서
파일 이름을 미리 정해놓고 그 이름으로 저장하며, 미리 날짜와 시간이 적혀 있는 메모장을 만들려면 어떻게 하나요?
날짜와 시간 정보를 가져오기 위해 datetime 라이브러리를 임포트합니다.
from tkinter import *
import datetime
날짜와 시간을 가져오기 위해 now() 함수로 현재 날짜와 시간을 가져오고 strftime() 함수로 지정한 형식의 문자열로 바꾸어 줍니다.
t = datetime.datetime.now().strftime("%y/%m/%e %H:%M")
%Y: 연도 (4자리), %y: 연도 (2자리), %d: 일 (01 ~ 31), %e: 일 (1 ~ 31), %H: 시간 (24시간), %I: 시간 (12시간)
미리 파일 이름을 정해둡니다.
myFile = 'my2023Meno.txt'
파일 저장 함수를 만듭니다.
def save_file():
global myFile
# utf-8 인코딩으로 추가하여 저장
f = open(myFile,'a', encoding="utf-8")
f.write(textBox.get(1.0, END))
f.close()
window.destroy() # 저장 후 창 닫기
기본적인 창과 텍스트 위젯을 만듭니다.
window = Tk()
window.title("메모장")
window.geometry("900x100+50+800")
# 창 크기와 위치
textBox = Text(master=window, wrap='word', font=("Arial", 20, 'bold'))
textBox.pack(fill=BOTH, expand=True)
textBox.focus_set()
textBox.insert(END, t) # 날짜 시간을 제일 끝에 넣기
extBox.insert(END, ' - ') # 옆줄 넣기
save_file 함수를 메인 창 닫기 단추에 연결(biding)
window.protocol("WM_DELETE_WINDOW", save_file)
window.mainloop()
'코딩배우기' 카테고리의 다른 글
파이썬 코딩 4 웹크롤링 (0) | 2023.08.22 |
---|---|
파이썬 코딩 3 유틸리티 (0) | 2023.08.21 |
파이썬 코딩 2 기본 활용 (0) | 2023.08.19 |
파이썬 코딩 1 기본 코딩법 (0) | 2023.08.18 |
스크래치 코딩 2 (0) | 2023.08.18 |