*주의* 이거저거 딴소리 많음 thread에 관해 필요한 정보는 아래에서 찾아가세요
저번 글에서 적었던 대로 제 알람에는 큰 문제가 있었어요.
1. Problems
가. 알람을 설정하기 위해서 set버튼을 클릭하면 맨 위에 시간이 흘러가지 않고 멈춘다.
나. set버튼을 누르면 (응답없음)이 떠서 현재시간과 1분 이상 차이나는 알람을 만들지 못한다.
기껏 알람을 만들었는데 오류가 떠서 몇 분 짜리 알람도 만들지 못한다니 너무 슬펐어요
다른 사람 블로그도 참고하고 특히 해외 사이트랑 유튜브도 꽤 참고했는데 많은 분들이 While True로 해서 하더라구요.
그래서 저도 그렇게 했는데 껍데기만 알람인 창이 되었습니다ㅋㅋㅋㅋ
2. set 버튼에 command 인 set_alarm함수 정의
아래는 set버튼에 들어가는 command인 set_alarm함수인데
while True문이 계속 실행되어서 시간도 업데이트가 되지 않고 오류가 나는건가 싶어서 해결방법을 하루종일 검색했습니다.
결과적으로 보면 while True때문인 것은 맞지만 코드 자체가 틀려서 오류가 나는 것은 아니었어요...!
무슨 뜻인지 궁금하시다면 아래를 읽어주세요ㅎㅎ
# set버튼 클릭
def set_alarm(event):
# hour 입력 확인
# h = int(hourTime.get())
if hourTime.index("end") ==0:
msgbox.showwarning("경고","시간(hour)을 입력해주세요")
elif 0<= int(hourTime.get()) <=24:
# hour.set( Done")
pass # return : 전체 함수 빠져나감(set_alarm빠져나가기 때문에 밑에 분,초는 검사가 안됨)
else:
msgbox.showwarning("경고", "시간(hour)을 정확히 입력해주세요")
# min 입력 확인
m = minTime.get()
if len(m) ==0:
msgbox.showwarning("경고","분(min)을 입력해주세요")
elif 0 <= int(m) <= 60 :
# min.set(" Done")
pass
else:
msgbox.showwarning("경고", "분(min)을 정확히 입력해주세요")
# sec 입력 확인
s = secTime.get()
if len(s) == 0:
msgbox.showwarning("경고","초(sec)를 입력해주세요")
elif 0<= int(s)<=60 :
# sec.set(" Done")
pass
else:
msgbox.showwarning("경고", "초(sec)를 정확히 입력해주세요")
# 버튼 클릭했을 때, 입력된 숫자에 따라서 레이블 값 바꿔주기 ===================================
if 0<=int(hourTime.get())<=24 and 0<=int(m)<=60 and 0<=int(s)<=60:
label_var.set("Alarm has been set :)")
else:
label_var.set("Please check the time again.")
# 현재시간과 입력시간 비교하기================================================================
while True:
update_timelabel
if int(hourTime.get()) != datetime.datetime.now().hour or int(minTime.get()) != datetime.datetime.now().minute :
update_timelabel
time.sleep(1)
elif int(hourTime.get()) == datetime.datetime.now().hour and int(minTime.get()) == datetime.datetime.now().minute :
print("Time is up")
break
3. GUI - while True 오류나는 이유
while True문으로 하면 왜 오류가 나는지 검색을 해봤습니다.
제가 친 코드 자체가 틀린 거라고 생각을 하고 이거저거 검색을 하느라고 시간을 낭비했었는데요...
tkinter에서 해당 함수를 실행하는 데 오랜 시간이 걸리면 tkinter은 함수의 결과가 return 되지 않기 때문에 멈추는 현상이 발생하기 때문이라고 합니다.
(참고싸이트)
글 제목: 파이썬 무한루프 - GUI (응답없음)
글 제목: [Python] GUI와 Multi-Threading 사용 (GUI + Multi-Threading)
4. 그래서 해결책은?
[import Threading] : Threading 모듈 활용!
Multi-Threading을 활용하여 오랜 시간이 걸리는 연산을 다른 Thread에서 실행하면 된다고 합니다.
GUI 연산을 수행하는 Thread는 오랜 시간이 필요한 연산을 수행하지 않기 때문에 계속 GUI를 업데이트 할 수 있다.
5. thread 적용하기
이제 tkinter에서 while True가 아닌 Threading을 써줘야 한다는 것을 알았으니 제 코드에 적용해보도록 하겠습니다!
(import threading 도 해주었습니다^^)
# alarm thread 실행 =======================================================================
def th():
t1= threading.Thread(target=set_alarm, args=())
t1.daemon = True # 창끄면 알람 실행도 꺼짐 (코딩하면서 잘 돌아가는지 체크할 때 편해서 추가해놓음)
t1.start()
# 레이블 값 바꾸기
def label_change():
if 0<=int(hourTime.get())<=24 and 0<=int(minTime.get())<=60:
label_var.set("Alarm has been set :)") # stringvar()에는 configure속성이 없다.
else:
label_var.set("Please check the time again.")
# set버튼 클릭 ===============================================================================
def set_alarm():
# hour 입력 확인
h = hourTime.get()
# if hourTime.index("end") ==0: '빈 칸이다' 이렇게도 표현 가능
if len(h) == 0:
msgbox.showwarning("warning","Please enter the hour.")
elif 0<= int(hourTime.get()) <=24:
pass # return : 전체 함수 빠져나감(set_alarm빠져나가기 때문에 밑에 분,초는 검사가 안됨)
else:
msgbox.showwarning("warning", "Please check the hour again.")
# min 입력 확인
m = minTime.get()
if len(m) ==0:
msgbox.showwarning("warning","Please enter the minute.")
elif 0 <= int(m) <= 60 :
pass
else:
msgbox.showwarning("warning", "please check the minute again.")
label_change()
# 알람시간과 현재시간 비교하기==========================================================
user_hour= int(h)
user_min= int(m)
now_hour = datetime.datetime.now().hour
now_min= datetime.datetime.now().minute
while user_hour != now_hour or user_min != now_min :
# now_hour를 현재시간으로 계속 바꿔줌 (real time으로 바껴야지 알람시간과 비교가능!)
now_hour = datetime.datetime.now().hour
now_min= datetime.datetime.now().minute
if user_hour == now_hour and user_min == now_min :
msg= msgbox.showinfo("Alarm","It is time")
사실 처음에는 thread가 뭔지도 모르고 해결될 거라는 기대감에 부풀어가지고 다른 분 코드를 참고해서 제 꺼에 적어봤는데 문제없이 실행이 되더라구요 >3< 정말 감동했습니다....ㅎㅎ
하지만 '오 되는군'하고 넘어가면 실력이 늘지 않는다고 꼭 이유를 알아봐야 한다는 글을 많이 봤어서
이유를 알아보고자 Thread에 대해 공부를 해보았습니다!
Threading
저는 아래 2가지 물음에 집중해서 검색을 해보았어요.
1. Threading 이란?
3. Threading 은 왜 쓰는가?
2. Threading 모듈은 어떻게 쓰는 것인가?
제가 공부하면서 많이 참고했던 주소들이에요
이 4가지 정도만 확인하시면 thread에 대해서도 많이 깊지는 못해도 어느 정도는 이해하실 수 있을거에요!
(자세한 내용은 다음에 따로 글을 쓸 예정이에요)
(참고싸이트)
다. (영어) 기본개념 설명 잘되어있는 영어 유튜브(완전 좋음)
라. (영어) threading이용해서 tkinter로 alarm 만들기 유튜브
앞으로 공부할 것들
1. GIL
이번 오류를 해결하고 threading에 대해 공부하면서 GIL 이라는 단어를 많이 보았습니다.
그래서 검색도 하고 유튜브도 봤지만 확실히 이해가 되지 않더라구요
그래서 앞으로 공부하면서 GIL 에대해서도 더 확실히 알아볼 거에요
(참고자료) GIL설명:
wangin9.tistory.com/entry/pythonthreadGIL
2. 설정한 알람을 리스트에 추가하는 방법
알람을 설정하고 리스트에서 알람시간을 확인할 수 있도록 해야할텐데,
set버튼을 누를 때마다 설정된 알람이 모두 작동하는지 확인이 먼저 필요할 거 같아요.
그리고 리스트에 뜨도록 하려면 어떻게 해야 될지도 알아봐야겠어요
진짜 어떻게 해야할지 막막하네요ㅋㅋㅋㅋ
3. 설정한 알람이 울리면 리스트에서 자동으로 삭제되는 방법
2번보다 더 막막한 것 같아요
어떻게 하면 자동으로 지워질 수 있을까 생각은 참 쉬운데 그걸 논리적으로 풀어가는 게 너무나 어려워요
4. 취소버튼을 누르면 쓰레드가 종료/정지(?)될 수 있도록 하는 코드
제가 리스트에서 선택한 시간의 쓰레드만 종료시키려면 어떻게 해야할까요?
리스트 목록에 하나하나 시간에 대해 정의를 해둬야할까요...?
검색해보니 True, False같은 거로 종료시키는 게 있던데 일단 그런거부터 알아봐야겠어요!
느낀 점(중간점검)
이번 일을 통해 스스로 프로젝트를 정하고 해나가면서 생긴 오류에 대해 알아가고 고치는 과정을
연하게나마 경험해 본 것 같습니다.
직업으로 삼으신 분들이 보시기에는 '살짝 엄지발톱을 담궈봤네' 정도의 수준이겠지만
저는 이런 경험을 해본 것만으로도 기쁘고 이 과정을 통해 성장한 것 같아서 굉장히 기뻤습니다.
생각지도 못한 곳에서 문제가 발생하고 뭐가 문제인지 알아내는 것부터가 시작이었던 힘든 과정이었지만
해결해나가면서 뿌듯했고 퇴근 후에 쉬고 싶지만 도서관에서도 계속 하게 될만큼 재미있었어요.
사실 저같은 초보에게는 모든 코드 한줄한줄이 이러한 과정이었어요.
Label에 글자를 set버튼을 눌렀을때 입력한 숫자에 따라서 if를 활용해서 바꿔주고 싶다고 구상을 했지만,
뭐부터 시작을 해야할 지 몰랐죠.
계속 검색을 하다보니 Stringvar()를 이때 활용해야 한다는 것을 알게되었고 configure인지 set인지 그런게 뭔지 알아보는 과정이 뒤따랐습니다.
그리고 제가 습득한 내용을 토대로 코드를 쳐봤지만 바로 오류가 나서 왜 그런지 알아보려고 또 관련해서 공부를 하게되었구요
그렇게 거듭된 오류를 통해서 배우고배워서 결국 제가 구현하고 싶었던 것을 구현할 수 있었어요.
진짜 만든 결과는 허접해 보이지만ㅠㅠㅠㅠ 그래도 많이 배울 수 있었던 것 같아요
앞으로 더 추가해줄 내용들이 많으니 그에 대해서도 공부하고 또 오류를 해결하면서 완성시켜줄 예정입니다!
리스트도 추가해야 하고 취소 버튼도 추가해야하니 다음 글도 얼른 쓸 수 있으면 좋겠네요ㅎㅎ
(+) 혹시 저처럼 비전공이지만 개발을 해보고 싶으신 분이 있다면
'해볼까 말까', '이게 도움이 될까 괜히 시간낭비만 되는게 아닐까' 생각만 하지마시고 짬짬히라도 시간을 내셔서
꾸준히 해보시면 분명 무언가를 꾸준히 하는 태도의 중요성과 그를 통해 얻을 수 있는 보람, 나는 어떻게 공부하는 게 가장 효율적인지, 나는 어떤 걸 좋아하는지 등등에 대해 크고 작은 깨달음을 얻으실 수 있을거라고 생각해요!
'Python' 카테고리의 다른 글
[python] list comprehension(리스트 내포) (0) | 2020.11.07 |
---|---|
[python] for _ in range (0) | 2020.10.31 |
[python_gui] 2. Alarm 만들기(오류 및 안되는 점 정리) (0) | 2020.10.11 |
[python_gui] 1. Alarm 만들기 (0) | 2020.10.05 |
[python_gui] frame 예쁘게 조정하기 (0) | 2020.10.01 |