진행 상태를 알려주는 GUI로 Label 의 값을 계속 변경해 줄 수도 있지만,
좀 더 시각적이고 가시적으로 보여주기위해서는 progressbar를 이용해보는게 좋다.
1. 코드
- 이번에도 tkiner.ttk 라이브러리를 사용한다.
- 단순히 Progressbar 객체(위젯)를 생성하는 것은 한두 줄의 코드로 되지만,
우리가 원하는 것처럼 진행하기 위해서는 몇가지 옵션이 필요하다.
- 파라미터별 비교를 위해 progressbar1~3을 각각 만들었다.
from tkinter import *
import tkinter.ttk
root = Tk()
root.title('To올라운드의 알찬 GUI 강의')
root.geometry("300x500") # 가로 X 세로 / 대문자X 하면 실행안됨
#msb.showinfo('Welcome','안녕하세요. To올라운더와 함께 하는 GUI입니다.')
def progressbar_start():
#progressbar1.start()
progressbar2.start(1000) # 1000 ms 마다 움직임, 1000ms = 1s
progressbar3.start(1000)
def progressbar_stop():
progressbar1.stop()
progressbar2.stop()
progressbar3.stop()
body_frame = Frame(root, relief='solid', bd=2, background='orange', padx=5, pady=5)
body_frame.pack(fill='both', expand=True)
progressbar1_label = Label(body_frame, text='Progressbar1')
progressbar1_label.pack()
progressbar1 = tkinter.ttk.Progressbar(body_frame, maximum=100, mode='indeterminate')
progressbar1.pack()
progressbar2_label = Label(body_frame, text='Progressbar2 / mode = indeterminat')
progressbar2_label.pack()
progressbar2 = tkinter.ttk.Progressbar(body_frame, maximum=100, mode='indeterminate')
progressbar2.pack()
progressbar3_label = Label(body_frame, text='Progressbar3 / mode = determinat')
progressbar3_label.pack()
progressbar3 = tkinter.ttk.Progressbar(body_frame, maximum=100, mode='determinat')
progressbar3.pack()
progressbar_start_btn = Button(body_frame, text='진행바 시작', command=progressbar_start)
progressbar_start_btn.pack(fill='x')
progressbar_stop_btn = Button(body_frame, text='진행바 중지', command=progressbar_stop)
progressbar_stop_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()
- progressbar1~3을 비교해보면
- progressbar1 은 progressbar_start 메서드에서 주석처리가 되어 start를 진행하지 않는다.
당연히, 멈춰있고 아무런 반응이 없는데 progressbar는 start와 stop 메서드에 따라 동작하게 된다.
- progressbar2 의 경우, indeterminate mode를 사용 중인데, 첨부된 동영상에서 보듯이
진행률이 진행됨에 따라 진행커서(초록색)이 움직이게 된다.
- 대신 determinate mode를 지정한 progressbar3의 경우에는
진행률이 진행됨에 따라 진행커서(초록색) 영역이 확장되며 채워진다.
- 그 외에도 공통적인 사항으로 start와 stop 메서드가 있는데,
start 메서드의 경우, 전달되는 값에 따라 ms 단위로 진행바가 움직인다. 1000을 입력하게 되면 1초마다 움직이고, 숫자가 작아질수록 더 빨리 움직인다.
- 그런데, stop을 하지 않고 기다려보면 progressbar가 계속 움직이는 것을 볼 수 있는데, 수동으로 stop을 할 수도 있지만
우리가 원하는 진행 상태를 확인하기 위해서는 특정 변수와 연결시켜야한다.
2. 응용하기
from tkinter import *
import tkinter.ttk
import time
root = Tk()
root.title('To올라운드의 알찬 GUI 강의')
root.geometry("300x500") # 가로 X 세로 / 대문자X 하면 실행안됨
#msb.showinfo('Welcome','안녕하세요. To올라운더와 함께 하는 GUI입니다.')
def progressbar_start():
#progressbar1.start()
progressbar2.start(10) # 1000 ms 마다 움직임, 1000ms = 1s
progressbar3.start(10)
def progressbar_stop():
progressbar1.stop()
progressbar2.stop()
progressbar3.stop()
body_frame = Frame(root, relief='solid', bd=2, background='orange', padx=5, pady=5)
body_frame.pack(fill='both', expand=True)
progressbar1_label = Label(body_frame, text='Progressbar1')
progressbar1_label.pack()
progressbar1 = tkinter.ttk.Progressbar(body_frame, maximum=100, mode='indeterminate')
progressbar1.pack()
progressbar2_label = Label(body_frame, text='Progressbar2 / mode = indeterminat')
progressbar2_label.pack()
progressbar2 = tkinter.ttk.Progressbar(body_frame, maximum=100, mode='indeterminate')
progressbar2.pack()
progressbar3_label = Label(body_frame, text='Progressbar3 / mode = determinat')
progressbar3_label.pack()
progressbar3 = tkinter.ttk.Progressbar(body_frame, maximum=100, mode='determinat')
progressbar3.pack()
# 변수와 진행률 연동하기
def increse_success_rate():
for i in range(0, 101):
time.sleep(0.01)
success_rate.set(i) # progressbar value 값 설정
progressbar4.update() # 변경된 value 값이 progressbar 에 적용(미사용시 동작 안됨)
time.sleep(5)
success_rate = DoubleVar() # 소수점 단위처리를 위해 Double 사용
progressbar4_label = Label(body_frame, text='Progressbar4 / 변수 연동')
progressbar4_label.pack()
progressbar4 = tkinter.ttk.Progressbar(body_frame, maximum=100, mode='determinat', variable=success_rate)
progressbar4.pack()
progressbar_start_btn = Button(body_frame, text='진행바 시작', command=progressbar_start)
progressbar_start_btn.pack(fill='x')
progressbar_stop_btn = Button(body_frame, text='진행바 중지', command=progressbar_stop)
progressbar_stop_btn.pack(fill='x')
progressbar4_run_btn = Button(body_frame, text='진행바4 시작', command=increse_success_rate)
progressbar4_run_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()
- progressbar4 를 새로 생성할 때 variable 변수를 사용한다.
- 시간 딜레이를 주기위해 time 라이브러리를 사용하였는데,
해당 시간(초) 동안 프로그램이 대기하는 기능이다.
- 소수점 단위 처리를 위해 DoubleVar() 로 생성하였는데,
예시 코드처럼 i 값이 변하는 것에 따라 적용하는 방법도 있지만,
예를 들어 전체 건수 2000 건 중 현재 진행 상태에 따라 해당 값을 반복해서 넣어주어도 진행 상태가 처리된다.
(1번째 처리 1/2000, 2번째 처리 2/2000 ........1000번째 처리 1000/2000) 이런 식의 값을 i에 할당하면된다.
- 51라인과 같이 해당 변수 값이 변할 때 해당 progressbar에 update를 진행해주면 해당 값이 반영된다.
- 마지막 완료 후, 전체 progressbar가 5초 멈추는 것을 볼 수 있는데, increse_success_rate 메서드의 마지막에
5초 delay가 할당되어 있기 때문이다.
- 하나의 매서드가 멈춰도 다른 매서드가 동작하기 위해서는 Thread(쓰레드) 라는 기능을 알아야한다.
(배워야 할 것이 점점 많아진다는 생각이 든다면 내 실력도 그만큼 늘어나고 있다는 걸 잊지말자.)
3. 그 외 옵션 파라미터
파라미터 | 의미 | 기본값 | 속성 |
length | 프로그래스 바의 너비 | 100 | 상수 |
orient | 프로그래스 바의 표시 방향 | vertical | vertical, horizontal |
mode | 프로그래스 바의 표시 스타일 | determinate | determinate, indeterminate |
'Python > GUI(tkinter)' 카테고리의 다른 글
독학 Python tkinter(GUI) - 19.Last piece1(thread) (0) | 2023.11.22 |
---|---|
독학 Python tkinter(GUI) - 18.Menubutton (1) | 2023.11.16 |
독학 Python tkinter(GUI) - 16.photoimage(+PIL) (0) | 2023.11.14 |
독학 Python tkinter(GUI) - 15.Combobox (0) | 2023.11.13 |
독학 Python tkinter(GUI) - 14.radiobutton(+LabelFrame) (0) | 2023.11.12 |