一定の期間、 Tkinterウィンドウの背景を最初の 16 進数の色から最後の 16 進数の色にフェードさせ、その間にいくつかの色を表示するプログラムを書きたいと思います。(行 99 のコメントを外すとprint time, hex_color_t
、明確でない場合は、私の意味が明確になるはずです。)
コードは次のとおりです。
from Tkinter import *
from ttk import *
import re
class InvalidColor(Exception):
pass
def color_to_hex(color):
MIN_COLOR = 0
MAX_COLOR = 255
try:
if color >= MIN_COLOR and color <= MAX_COLOR:
try:
hex_str = hex(color)[2:]
except TypeError:
raise InvalidColor
if len(hex_str) < 2:
hex_str = "0" + hex_str
return hex_str
else:
raise InvalidColor
except InvalidColor:
return "00"
def rgb_to_hex((red, green, blue), upper = True):
r = color_to_hex(red)
g = color_to_hex(green)
b = color_to_hex(blue)
hex_str = "#%s%s%s" % (r, g, b)
if upper:
hex_str = hex_str.upper()
return hex_str
def hex_to_rgb(hex_value):
hex_pattern = re.compile(r"^(#)?(?P<r>[a-f0-9]{2})(?P<g>[a-f0-9]{2})(?P<b>[a-f0-9]{2})$", re.IGNORECASE)
match = hex_pattern.match(hex_value)
HEX_PREFIX = "0x"
BASE = 16
if match:
# could be more DRY-ish, but whatever
r = int(HEX_PREFIX + match.group("r"), BASE)
g = int(HEX_PREFIX + match.group("g"), BASE)
b = int(HEX_PREFIX + match.group("b"), BASE)
else:
raise InvalidColor
return (r, g, b)
#print rgb_to_hex((255, 0, 0))
#print type(hex_to_rgb(rgb_to_hex((107,142,35))))
#print hex_to_rgb("4B0082")
root = Tk()
initial_color_hex = "#0000ff" # blue
final_color_hex = "#44ccff" # light blue
STOP_TIME_MS = 2000
STEP_TIME_MS = 50
"""
def final_color(*args, **kwargs):
root.configure(background = final_color_hex)
"""
def set_color(root, hex_color, *args, **kwargs):
root.configure(background = hex_color)
def linear_fade(root,
hex_start_color,
hex_stop_color,
stop_time_ms = STOP_TIME_MS,
step_time_ms = STEP_TIME_MS,
delay_ms = 0):
root.configure(background = hex_start_color)
(r0, g0, b0) = hex_to_rgb(hex_start_color)
(rf, gf, bf) = hex_to_rgb(hex_stop_color)
delta_r = rf-r0
delta_g = gf-g0
delta_b = bf-b0
#print delta_r, delta_g, delta_b
for time in range(delay_ms, stop_time_ms+1, step_time_ms):
rt = r0 + (delta_r * time // stop_time_ms)
gt = g0 + (delta_g * time // stop_time_ms)
bt = b0 + (delta_b * time // stop_time_ms)
#print (rt, gt, bt)
hex_color_t = rgb_to_hex((rt,gt,bt))
#print time, hex_color_t
root.after(time, set_color(root, hex_color_t))
root.configure(background = initial_color_hex)
#root.after(1000, final_color)
root.geometry("400x400")
linear_fade(root, initial_color_hex, final_color_hex)
root.mainloop()
これまでのところ、ウィンドウを作成せずにループを通過しているように見えるfor
ので、遅延してから背景として最終的な色になります。
もっと最小限の実用的な例に行くべきだと思います。私は試した:
from Tkinter import *
root = Tk()
initial_color_hex = "#0000ff" # blue
final_color_hex = "#44ccff" # light blue
def set_color(hex_color, *args, **kwargs):
root.configure(background = hex_color)
root.configure(background = initial_color_hex)
root.after(1000, set_color(final_color_hex))
root.geometry("400x400")
root.mainloop()
しかし、私はまだ同じ問題に遭遇します。私はどこかでうまくいくものを見つけました:
try:
import tkinter
except ImportError:
import Tkinter as tkinter
root = tkinter.Tk()
def grey(*args,**kwargs):
root.configure(background = "grey")
def bthing():
root.configure(background = "red")
root.after(1000, grey)
tkinter.Button(text = "OK", command = bthing).pack()
root.configure(background = "grey")
root.geometry("400x400")
root.mainloop()
しかし、これら 2 つの例の決定的な違いは何でしょうか?