1. Introduction
Python Turtle 그래픽과 Tkinter 그래픽을 같이 혼합 연동해서 사용하는 예제입니다. 약간 혼동을 가져올 수도 있겠습니다만, 이런 방식도 있다는 것을 알아 둘 필요는 있습니다. ~~.pack() 옵션에 따라 버튼의 모양이 달라집니다. pack() 옵션에 대해서는 다음 시간에 살펴보겠습니다. 이 예제와 함께 이전 예제들도 복습하면 좋겠습니다.
이번 예제에서는 turtle 모듈의 그리기 속도를 개선하는 문제를 중심으로 살펴보겠습니다.
2. Code
import turtle
import tkinter as tk
tkWin = tk.Tk()
tkWin.geometry("800x400")
tkWin.title("LOGO 연습")
tWin = turtle.Screen()
tWin.setup(1600, 768, 40, 40) # 거북이 윈도우의 크기와, 위치 결정. width, height, x, y.
tWin.mode("LOGO") # "standard" 모드가 기본.
tWin.delay(0) # 그리기 지연 속도를 '없음zero'(으)로 설정해서 최대 속도로 그림.
j1 = turtle.Turtle() # j = turtle.Pen()로 대체 가능.
j1.speed(0) # speed(0) : 그리기 속도 자체를 최대치로 높임.
j1.shape("turtle")
j1.shapesize(1)
# 참고 : j1.speed(10)이 가장 빠르다.
# 동급. 0은 속도가 없음? 속도 제한이 없음의 뜻. 다만 실제로는 0이 좀 더 빠르게 그려지는 듯.
# 'turtle.delay(0)'와 협력해서 최도 속도로 그립니다.
turtle.tracer(2, 50)
# turtle.tracer(n, delay) 함수를 사용하여 애니메이션을 비활성화하거나 업데이트 빈도를 줄일 수 있습니다.
# n은 업데이트 빈도를 의미하며, delay는 밀리초 단위의 지연 시간을 의미합니다.
# 예를 들어, turtle.tracer(0, 0)은 애니메이션을 비활성화합니다.
#
# tracer() 함수에 0이 아닌 다른 파라미터 값이 들어가면 어쨌든 그려지는 시간이 좀 더 걸린다.
# 하지만, tracer(0, 0)에서는 약간의 버그가 있는 것으로 생각된다.
# 원인 불명, box1() 함수가 제대로 실행되지 않는다. ^.^;
# 대안으로 turtle.tracer(1, 1)로 하면 box1() 그리기 버그는 해결된다.
# 하지만 이번에는 box64() 속도가 현저하게 느려진다.
# (2, 50)은 테스트 절충안임.
# 다음 값들을 테스트해보세요.
# turtle.tracer(0, 0)
# turtle.tracer(1, 1)
# turtle.tracer(2, 50)
def setup():
pass # 정상 작동되는 코드임. 내용 입력을 보류할 때 주로 사용.
def box1():
for i in range(4):
j1.fd(100)
j1.lt(90)
def box64():
turtle.tracer(0, 0) # 이 줄이 없으면 box64() 그리기가 느려진다.
for i in range(64):
box1()
j1.pu()
j1.fd(20)
j1.lt(5)
j1.pd()
def clearAll():
tWin.resetscreen()
turtle.tracer(2, 50) # 이 줄이 없으면, box1() 그리기에 문제가 생긴다. (2, 50)은 테스트 절충안임.
jBtn1 = tk.Button(tkWin, text="box1()", command=box1)
jBtn1.pack(padx=0, pady=0, ipadx=20, ipady=20, side=tk.LEFT, expand=True, fill=tk.BOTH)
jBtn2 = tk.Button(tkWin, text="box64()", command=box64)
jBtn2.pack(padx=0, pady=0, ipadx=20, ipady=20, side=tk.LEFT, expand=True, fill=tk.BOTH)
jBtn3 = tk.Button(tkWin, text="clearAll()", command=clearAll)
jBtn3.pack(padx=0, pady=0, ipadx=20, ipady=20, side=tk.LEFT, expand=True, fill=tk.BOTH)
setup() # 유보 함수. 필요시 내용 추가. ^.^;
tkWin.mainloop()
3. Result
4. Notes
파이썬 Turtle 모듈에서의 애니메이션 그리기 속도 문제를 개선하려고 합니다. Turtle 모듈에서는 기본적으로 애니메이션 형태로 그림이 그려집니다. 즉, 결과를 보려면 그려지는 시간이 걸리게 됩니다. 복잡한 그림일 경우에는 많이 기다려야 합니다. 수정해야 할 경우, 문제가 될 수도 있습니다. 이 문제에 대응하고자 합니다.
그리기 속도 문제는 실제로는 약간 차이가 있을 수 있습니다. 직접 실험 실습을 해보는 것을 권장합니다.
■ Python turtle 모듈 그리기 속도 개선 :
Python의 turtle 모듈에서 그리기 속도를 높이려면 몇 가지 방법이 있습니다:
1) speed() 함수 사용 :
- turtle.speed(speed) 함수를 사용하여 속도를 설정할 수 있습니다. 여기서 speed는 0에서 10까지의 숫자 또는 문자열로 설정할 수 있습니다. 예를 들어, turtle.speed(10)은 가장 빠른 속도를 의미합니다. turtle.speed(0)이 좀 더 빠른 듯. 그리기 속도 제한 없음 정도.
2) 애니메이션 비활성화 :
- turtle.tracer(n, delay) 함수를 사용하여 애니메이션을 비활성화하거나 업데이트 빈도를 줄일 수 있습니다. n은 업데이트 빈도를 의미하며, delay는 밀리초 단위의 지연 시간을 의미합니다. 예를 들어, turtle.tracer(0, 0)은 애니메이션을 비활성화합니다.
3) update() 함수 사용 :
- 애니메이션을 비활성화한 후, 그리기 작업이 끝난 후 turtle.update() 함수를 호출하여 화면을 업데이트할 수 있습니다. 이 부분은 지금의 경우에는 큰 문제가 되지는 않을 듯. 사용법만 알아두는 것으로 여기서는 패스. ^.^;
예제 코드
import turtle
turtle.tracer(0, 0) # 그리기 작업
......
......
turtle.update() # 화면 업데이트
이 방법들을 사용하면 turtle 모듈에서 그리기 속도를 크게 향상시킬 수 있습니다.
참고 ::
■ 화면 갱신 빈도 n 프레임 ::
'turtle.tracer(n, delay)' 함수에서 'n'의 단위는 프레임 수입니다. 여기서 'n'은 거북이 그래픽의 화면 갱신 빈도를 제어합니다. 간단히 말해, 'n' 프레임마다 화면을 한 번 갱신합니다.
예를 들어:
- 'n=1'로 설정하면 모든 프레임이 화면에 표시됩니다. 즉, 모든 움직임이 실시간으로 보입니다.
- 'n=10'로 설정하면 10 프레임마다 한 번씩 화면이 갱신됩니다. 이는 애니메이션을 빠르게 실행할 때 유용합니다.
'delay'는 각 화면 갱신 사이의 지연 시간을 밀리초 단위로 설정합니다. 이 두 파라미터를 통해 애니메이션의 속도와 부드러움을 조절할 수 있습니다.
예시 :
python
import turtle
# 화면 갱신을 5 프레임마다 한 번씩 하며, 각 갱신 사이에 100밀리초 지연
turtle.tracer(5, 100)
for _ in range(50):
turtle.forward(10)
turtle.right(36)
turtle.done()
이 예시에서는 거북이가 10 픽셀씩 이동하고, 36도씩 회전하면서 별 모양을 그립니다. 'turtle.tracer(5, 100)' 설정 덕분에 화면 갱신이 덜 빈번하게 이루어져 애니메이션이 빠르게 보이지만 각 갱신 사이에 약간의 지연이 추가됩니다.
■ 기본 프레임 수 ::
'turtle' 모듈에서는 특정한 기본 프레임 수(FPS: Frames Per Second)가 명시적으로 설정되어 있지는 않습니다. 대신, 'turtle.tracer()' 함수의 매개변수와 'turtle.update()' 함수를 사용하여 애니메이션의 업데이트 빈도를 제어할 수 있습니다.
기본 설정으로는 'turtle.tracer(1, 0)'이 적용되어 모든 움직임이 실시간으로 반영됩니다. 하지만 이를 통해 FPS를 직접적으로 제어하기보다는, 프레임당 업데이트 빈도를 조정하여 원하는 애니메이션 효과를 얻을 수 있습니다.
예를 들어, 'turtle.tracer(n, delay)'에서 'n' 값을 높이면 화면이 덜 빈번하게 갱신되어 애니메이션이 빠르게 보일 수 있습니다. 'delay' 값을 설정하면 갱신 사이의 지연 시간을 추가하여 애니메이션을 더 부드럽게 만들 수 있습니다.
추가적인 제어를 위해 'time.sleep()' 함수를 사용하여 딜레이를 적용하거나, 루프 내에서 특정 동작 후에 'turtle.update()'를 호출하여 화면을 갱신할 수 있습니다.
■ n의 최대값 ::
'turtle.tracer(n)' 함수에서 'n'의 최대값은 명시되어 있지 않습니다. 그러나 현실적으로 너무 큰 값을 설정하면 애니메이션이 너무 빠르게 실행되거나, 거북이 그래픽의 움직임이 사실상 보이지 않게 될 수 있습니다.
일반적으로 적절한 'n' 값을 설정하여 애니메이션을 최적화하는 것이 중요합니다. 예를 들어, 'n'을 1로 설정하면 모든 프레임이 갱신되고, 10으로 설정하면 10 프레임마다 한 번씩 화면이 갱신됩니다. 너무 큰 값을 설정하는 것은 권장되지 않습니다.
프로젝트의 필요에 따라 'n' 값을 조정해 보시고, 최적의 성능을 찾는 것이 좋습니다.
5. Update - 01 : 가장 빠른 그리기 최종 해법
■ turtle.tracer(0, 0)에서 box1() 함수 실행 결과가 제대로 표시되지 않는 문제는 box1() 함수의 끝에 turtle.update() 라인을 추가하면 해결되는 듯 합니다. 그럼 turtle.tracer(0, 0)도 문제없이 사용할 수 있을 듯. 다만 이 경우, box1() 함수를 사용하는 box64() 함수의 속도는 update()의 반복 호출로 느려집니다.
그래서 최종 해법은 box64() tk 버튼을 클릭할 때만 적용할 수 있는 새 함수 newBox() 함수를 만들고 여기에 box1(), upate()를 포함시키면 됩니다.
■ 예제 코드 (첨부 파일 : Tkinter_Speed_Ex_003_Final_.py)
import turtle
import tkinter as tk
tkWin = tk.Tk()
tkWin.geometry("800x400")
tkWin.title("LOGO 연습")
tWin = turtle.Screen()
tWin.setup(1600, 768, 40, 40) # 거북이 윈도우의 크기와, 위치 결정. width, height, x, y.
tWin.mode("LOGO") # "standard" 모드가 기본.
tWin.delay(0) # 그리기 지연 속도를 '없음zero'로 설정해서 최대 속도로 그림.
j1 = turtle.Turtle() # j = turtle.Pen()로 대체 가능.
j1.speed(0) # speed(0) : 그리기 속도 자체를 최대치로 높임.
j1.shape("turtle")
j1.shapesize(1)
# 참고 : j1.speed(10)이 가장 빠르다.
# 동급. 0은 속도가 없음? 속도 제한이 없음의 뜻. 다만 실제로는 0이 좀 더 빠르게 그려지는 듯.
# 'turtle.delay(0)'와 협력해서 최고 속도로 그립니다.
turtle.tracer(0)
# turtle.tracer(0, 0)과 같습니다.
# turtle.tracer(n, delay) 함수를 사용하여 애니메이션을 비활성화하거나 업데이트 빈도를 줄일 수 있습니다.
# n은 업데이트 빈도를 의미하며, delay는 밀리초 단위의 지연 시간을 의미합니다.
# 예를 들어, turtle.tracer(0, 0)은 애니메이션을 비활성화합니다.
#
# tracer() 함수에 0이 아닌 다른 파라미터 값이 들어가면 어쨌든 그려지는 시간이 좀 더 걸린다.
# 하지만, tracer(0, 0)에서는 약간의 버그가 있는 것으로 생각된다.
# 원인 불명, box1() 함수가 제대로 실행되지 않는다. ^.^;
# 대안으로 turtle.tracer(1, 1)로 하면 box1() 그리기 버그는 해결된다.
# 하지만 이번에는 box64() 속도가 현저하게 느려진다.
# (2, 50)은 테스트 절충안임.
def setup():
pass
def box1():
for i in range(4):
j1.fd(100)
j1.lt(90)
def box64():
# turtle.tracer(0, 0) # 이 줄이 없으면 box64() 그리기가 느려진다. 하지만 이제는 없어도 무방.
for i in range(64):
box1()
j1.pu()
j1.fd(20)
j1.lt(5)
j1.pd()
def newBox1():
box1()
turtle.update()
def clearAll():
tWin.resetscreen()
# turtle.tracer(0, 0) # 이 줄이 없으면, box1() 그리기에 문제가 생긴다. (2, 50)은 테스트 절충안임. 이제는 불필요.
jBtn1 = tk.Button(tkWin, text="box1()", command=newBox1)
jBtn1.pack(padx=0, pady=0, ipadx=20, ipady=20, side=tk.LEFT, expand=True, fill=tk.BOTH)
jBtn2 = tk.Button(tkWin, text="box64()", command=box64)
jBtn2.pack(padx=0, pady=0, ipadx=20, ipady=20, side=tk.LEFT, expand=True, fill=tk.BOTH)
jBtn3 = tk.Button(tkWin, text="clearAll()", command=clearAll)
jBtn3.pack(padx=0, pady=0, ipadx=20, ipady=20, side=tk.LEFT, expand=True, fill=tk.BOTH)
setup()
tkWin.mainloop()
6. Files
Not yet! ^.^;
7. Ref.
■ 참고 자료 :
1) [Python 터틀 그래픽 - 제6강 turtle 모듈 명령어 정리]
(https://m.blog.naver.com/python_math/221214856867)
2) [turtle — 터틀 그래픽 — Python 3.14.0a1 문서]
(https://docs.python.org/ko/dev/library/turtle.html)
3) [파이썬 기본패키지 turtle 모듈 사용법]
(https://proprogramming.tistory.com/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC%EA%B8%B0%EB%B3%B8%ED%8C%A8%ED%82%A4%EC%A7%80-turtle%EC%82%AC%EC%9A%A9%EB%B2%95)
■ 기타 추가 참고 자료 :
(1) Python 터틀 그래픽 - 제6강 turtle 모듈 명령어 정리 : 네이버 블로그.
https://m.blog.naver.com/python_math/221214856867
(2) turtle — 터틀 그래픽 — Python 3.14.0a1 문서.
https://docs.python.org/ko/dev/library/turtle.html
(3) 거북이로 그림그리기(turtle 모듈) - 파이썬 실전 프로젝트.
https://opentutorials.org/course/3094/17289
(4) turtle 모듈 명령어 정리!! / 터틀그래픽 : 네이버 블로그.
https://m.blog.naver.com/sweetygangx2/221901094941
Happy Programming!
^.^;
'Programming > Python' 카테고리의 다른 글
[ 고급 ] 파일명 유틸리티 SR. (v.0.0.2 beta 002) - Updates #3, 4 (0) | 2024.11.26 |
---|---|
Tkinter 기본 연습 - 1 : 버튼과 pack() 사용법 (0) | 2024.10.26 |
UniCode 연습 - 001 (0) | 2024.10.09 |
[ 고급 ] 파일명 관리 유틸리티 SR. (v.0.0.2 beta 001) (0) | 2024.10.06 |
[ L2P ] Python 입문 - Turtle 모듈 - 001 (0) | 2024.09.15 |