Python:tkinter
tkinter 패키지(《Tk 인터페이스》)는 Tk GUI 툴킷에 대한 표준 파이썬 인터페이스입니다. Tk와 tkinter는 대부분의 유닉스 플랫폼과 윈도우 시스템에서 사용할 수 있습니다. (Tk 자체는 파이썬 일부가 아닙니다; ActiveState에서 유지 보수됩니다.)
명령 줄에서 <codee>python -m tkinter</code>를 실행하면 간단한 Tk 인터페이스를 보여주는 창을 열어, tkinter가 시스템에 제대로 설치되었는지 알 수 있도록 하고, 설치된 Tcl/Tk 버전을 보여주기 때문에, 그 버전에 해당하는 Tcl/Tk 설명서를 읽을 수 있습니다.
Widgets
- Button - 단순한 버튼
- Label - 텍스트 혹은 이미지 표시
- CheckButton - 체크박스
- Entry - 단순한 한 라인 텍스트 박스
- ListBox - 리스트 박스
- RadioButton - 옵션 버튼
- Message - Label과 비슷하게 텍스트 표시. Label과 달리 자동 래핑 기능이 있다.
- Scale - 슬라이스 바
- Scrollbar - 스크롤 바
- Text - 멀티 라인 텍스트 박스로서 일부 Rich Text 기능 제공
- Menu - 메뉴 Pane
- Menubutton - 메뉴 버튼
- Toplevel - 새 윈도우를 생성할 때 사용. Tk()는 윈도우를 자동으로 생성하지만 추가로 새 윈도우 혹은 다이얼로그를 만들 경우 Toplevel를 사용한다
- Frame - 컨테이너 위젯. 다른 위젯들을 그룹화할 때 사용
- Canvas - 그래프와 점들로 그림을 그릴 수 있으며, 커스텀 위젯을 만드는데 사용될 수도 있다
Open File Dialog
Python:tkinter with OpenCV
OpenCV를 Python:Tkinter에 그리는 방법. OpenCV:Example:Tkinter 항목 참조.
컴포넌트를 윈도우 크기에 맞춰 변하게 하기
pack
함수를 쓸 때 인자를 주의하자.
Event Object
이벤트핸들러(이벤트 콜백)는 event라는 하나의 파라미터를 갖는데, 이는 Tkinter Event Object 로서 다음과 같은 속성(attribute)들을 갖는다. 위의 #2 예제를 보면, click() 함수에서 event 파라미터를 받아들이고, 이 event의 x, y 좌표를 사용하고 있음을 알 수 있다.
-
char
- 키보트 이벤트에서 발생하는 문자 하나 -
keysym
- 키보트 이벤트에서 발생하는 키의 심볼명 -
num
- 마우스 이벤트의 버튼 번호. 왼쪽부터 1, 2, 3 -
x
,y
- 위젯의 죄상단으로부터의 상대적 마우스 위치 -
x_root
,y_root
- 화면 죄상단으로부터의 상대적 마우스 위치 -
Key
- 이벤트가 발생한 위젯
Asyncio with tkinter
import tkinter as tk
from tkinter import ttk
import asyncio
class App:
async def exec(self):
self.window = Window(asyncio.get_event_loop())
await self.window.show();
class Window(tk.Tk):
def __init__(self, loop):
self.loop = loop
self.root = tk.Tk()
self.animation = "░▒▒▒▒▒"
self.label = tk.Label(text="")
self.label.grid(row=0, columnspan=2, padx=(8, 8), pady=(16, 0))
self.progressbar = ttk.Progressbar(length=280)
self.progressbar.grid(row=1, columnspan=2, padx=(8, 8), pady=(16, 0))
button_block = tk.Button(text="Calculate Sync", width=10, command=self.calculate_sync)
button_block.grid(row=2, column=0, sticky=tk.W, padx=8, pady=8)
button_non_block = tk.Button(text="Calculate Async", width=10, command=lambda: self.loop.create_task(self.calculate_async()))
button_non_block.grid(row=2, column=1, sticky=tk.W, padx=8, pady=8)
async def show(self):
while True:
self.label["text"] = self.animation
self.animation = self.animation[1:] + self.animation[0]
self.root.update()
await asyncio.sleep(.1)
def calculate_sync(self):
max = 3000000
for i in range(1, max):
self.progressbar["value"] = i / max * 100
async def calculate_async(self):
max = 3000000
for i in range(1, max):
self.progressbar["value"] = i / max * 100
if i % 1000 == 0:
await asyncio.sleep(0)
asyncio.run(App().exec())
다른 버전
# This demo is a transliteration of the below referenced demo to use the async/await syntax
#
#https://www.reddit.com/r/Python/comments/33ecpl/neat_discovery_how_to_combine_asyncio_and_tkinter/
#
# For testing purposes you may use the following command to create a test daemon:
# tail -f /var/log/messages | nc -l 5900
# Enter localhost:5900 in the entry box to connect to it.
from tkinter import *
import asyncio
async def run_tk(root, interval=0.05):
'''
Run a tkinter app in an asyncio event loop.
'''
try:
while True:
root.update()
await asyncio.sleep(interval)
except TclError as e:
if "application has been destroyed" not in e.args[0]:
raise
async def tclient(addr,port):
print('tclient',addr,port)
try:
sock ,_= await asyncio.open_connection(host=addr,port=port)
#print(sock)
#f=sock.as_stream()
while True:
#data = yield from f.readline()
data = await sock.readline()
if not data:break
data=data.decode()
print(data,end='\n' if data[-1]=='\r' else'')
except:
pass
async def main():
root = Tk()
entry = Entry(root)
entry.grid()
def spawn_ws_listener():
addr=entry.get().split(':')
print('spawn',addr)
return asyncio.ensure_future( tclient( addr[0],int(addr[1]) ) )
Button(root, text='Connect', command=spawn_ws_listener).grid()
await run_tk(root)
if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
Troubleshooting
AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'
다음과 같은 에러가 나온다
해당하는 위치는:
from PIL.ImageTk import PhotoImage
from numpy import uint8, zeros
empty = zeros((height, width, 3), dtype=uint8)
photo = PhotoImage(empty)
다음과 같이 수정:
See also
- python
- Tcl/Tk
- PySimpleGUI
- Python:Tkinter
- TkinterWeb
- async-tkinter-loop
- Tkinter-Designer (Tkinter, Python, Figma)