파이썬 tkinter: 윈도우 vs 맥 OS
tkinter: 파이썬 GUI
Tkinter는 대표적인 파이썬 GUI 프로그래밍 패키지입니다. 주로 키보드에서 명령어를 입력하던 제가 최근 기존 프로그램에 tkinter로 GUI 환경을 붙여봤습니다. 한데 그 과정에서 맥 OS와 윈도우가 좀 다르게 작동한다는 사실을 알게 되었습니다. 파이썬과 tkinter의 버전에 따라 상황이 바뀔 수도 있겠습니다만, 어떻든 두 플랫폼에서 tkinter가 똑같이 돌지는 않을 수 있다는 이야기지요.
버튼의 백그라운드 색깔 설정
맥 OS에선 버튼의 백그라운드 색깔을 사용자가 바꿀 수 없었습니다. 프로그램에서 설정한 값이 아무런 영향도 미치지 못했기 때문입니다. 제가 장난감 삼아 R, G, B 값을 입력받아 그에 따른 색깔을 나타내는 코드를 짜 봤습니다. 그림 1에서처럼 윈도우 코드는 제대로 도는데, 맥에선 그냥 항상 검은색(R = 0, G = 0, B = 0)으로만 나오더군요. 그래서 맥에선 어쩔 수 없이 ‘Your color”라는 글씨를 쓰고 그 테두리 색깔을 바꾸는 방식을 선택해야 했습니다. 그림 2와 같이 말입니다.


요컨대 맥에선 background = “red” 같은 옵션이 제대로 작동하지 않았습니다. 그래서 highlightbackground = “red” 같은 편법을 사용했는데, 다른 (똘똘한) 해법도 물론 있으리라 여깁니다.
tkinter 창에서 matplotlib 그림 띄우기
Matplotlib는 파이썬의 대표적인 그림 그리기 패키지입니다. 파이썬이 익숙지 않은 분들은 gnuplot을 떠올려보셔도 괜찮을 듯합니다. 지금까지 matplotlib를 잘 써왔는데, 윈도우의 tkinter 창에서 그림을 띄우니 이상한 일이 일어나더군요. Matplotlib 창은 잘 나오는데, 그걸 부른 tkinter 창이 작아지지 뭡니까. 그림 3에서처럼 말입니다. 맥에선 생기지 않는 현상입니다. 이 문제는 matplotlib 그림을 tkinter 창 안에 담고 그 tkinter 창을 띄우는 방식으로 해결했습니다. 그 모습이 그림 4입니다.


요컨대 윈도우를 사용할 땐 tkinter 창에서 matplotlib 그림을 바로 띄우지 말고 tkinter 창 안으로 넣을 필요가 있습니다. 물론 모든 matplotlib 그림을 그리 처리해야 한다는 뜻은 아닙니다. Tkinter에서 matplotlib 그림을 불러오는 경우에 그렇다는 이야기지요. 아울러 파이썬이나 관련 패키지의 버전에 따라 이런 상황이 달라질 수도 있겠습니다.
코드
그림 3과 4는 SVD를 이용해 이미지를 압축하는 프로그램입니다. 자세한 내용은 여기 있습니다. 그림 1, 2와 관련한 코드는 간단해 여기 바로 붙입니다. (제가 20세기엔 주로 포트란과 C를 썼고, 21세기엔 매트랩으로 시뮬레이션을 해왔습니다. 파이썬은 초보란 이야기지요. 파이썬 코딩에 관한 조언, 대환영입니다!)
def rgb_color():
"""
For RGB to Color!
Coded by T.-W. Yoon on Aug. 3, 2021
"""
import tkinter as tk
import platform
platform_name = platform.system()
def show_color():
"""
Read integer values between 0 and 255 for R, G and B,
turn the resulting color into the form '#◻︎◻︎◻︎◻︎◻︎◻︎',
and show the color by reconfiguring the button widget.
Changing 'background' colors is not allowed in mac,
and therefore 'highlightbackground' is used instead.
On windows, bg='#◻︎◻︎◻︎◻︎◻︎◻︎' works fine.
"""
color_code = "#"
for val in values:
number = val.get()
hex_chr = hex(number)[2:]
if number < 16:
hex_chr = '0' + hex_chr
color_code += hex_chr
button_color_option = {
"highlightbackground": color_code
} if platform_name == 'Darwin' else {
"bg": color_code
}
button_color.config(**button_color_option)
####################################
# GUI for setting R, G, B values, #
# and plotting the resulting image #
####################################
base_color = {"bg": "white", "fg": "black"}
root = tk.Tk()
root.title("RGB to Color")
root.config(bg="white")
tk.Label(
root, text="Select the RGB values",
font=("Helvetica", 13),
**base_color, padx=15, pady=20
).pack(expand=tk.YES, fill=tk.BOTH)
colors = "R", "G", "B"
values = tk.IntVar(), tk.IntVar(), tk.IntVar()
for color, value in zip(colors, values):
frame = tk.Frame(root, bg="white")
frame.pack()
tk.Label(frame, text=color, **base_color, padx=10).pack(side=tk.LEFT)
tk.Scale(
frame, **base_color, variable=value, showvalue=True, from_=0, to=255,
length=290, tickinterval=255, orient=tk.HORIZONTAL, sliderlength=15,
command=lambda argument: show_color()
).pack(padx=15, side=tk.RIGHT)
button_initial_option = {
**base_color,
"text": "Your Color", "highlightthickness": 60,
"highlightbackground": "#000000"
} if platform_name == 'Darwin' else {
"width": 22, "height": 10,
"bg": "#000000"
}
button_color = tk.Button(root, **button_initial_option)
button_color.pack(padx=15, pady=30)
root.mainloop()
if __name__ == "__main__":
rgb_color()
댓글남기기