在 Tkinter 的主循环中更改显示的图像?
Changing a displayed image inside mainloop on Tkinter?
我正在尝试制作一个全屏显示单一颜色的程序。这个想法是在大屏幕上使用它来创造房间的环境,屏幕在一定时间后会从一种颜色变为另一种颜色。
全屏显示颜色没有问题,但我怎样才能顺利地改变所说的颜色?
对于全屏显示,我使用了与屏幕大小相同的 Tkinter window:imagesprite = canvas.create_image(w/2, h/2, image=image)
其中 image
是某种颜色。但是要更改颜色,我需要使用 root.after(2000, root.destroy)
破坏 window,然后创建一个新的。这并不流畅,因为可以看到短暂的桌面。
如何随时随地更改 Tkinter window 中显示的图像,或者,如何关闭一个 window 并顺利打开另一个?
您可以选择为 Canvas 对象设置背景而不是使用图像。这是具有单一颜色背景的最少代码。
from tkinter import Tk, Canvas
root = Tk()
root.attributes("-fullscreen",True)#Makes the window fullscreen
canvas = Canvas(root, width=root.winfo_width(),height=root.winfo_height(), background="red") #Makes a canvas with a red coloured background
#The width and height of the Canvas are taken from the root object
canvas.pack()
root.mainloop()
从这里开始,无需不断删除 window,只需更改 Tkinter 小部件的属性即可。这是使用 config 方法完成的。
canvas.config(background="green")
tkinter 的一大优点是你可以给它一个颜色的十六进制代码,它会使用它来绘制。它需要采用如下格式的字符串:
"#RRGGBB"
其中每组是一个从 0 到 FF 的十六进制数。
考虑到这一点,您可以增加每帧的十六进制数,或者增加两种颜色之间所需的任意帧数。要获得良好的过渡效果,您可能需要使用 Hue、Saturation、Value (HSV) 颜色,并且只更改 Hue 值。
您可以将 HSV 存储在列表中:
hsv = [0,0.7,0.7]
要转换,首先要转换为 0 到 255 RGB,然后再转换为十六进制。
import colorsys
rgb = colorsys.hsv_to_rgb(*hsv) #Uses list unpacking to give it as arguments
接下来,您使用 rgb 并将其转换为 Hexcode 格式。
def getHexCode(rgb):
r = hex(int(rgb[0]*255))[2:] #converts to hexadecimal
#With the hex() function, it returns a number in "0xFE" format (0x representing hex).
#To ignore this, we can take the substring using [2:]
if len(r) < 2: #If the value is a 1-digit number, then we want to add a zero at the front for hexcode form
r = "0"+r
g = hex(int(rgb[1]*255))[2:]
if len(g) < 2:
g = "0"+g
b = hex(int(rgb[2]*255))[2:]
if len(b) < 2:
b = "0"+b
return "#" + r + g + b
最后,我们真正调用了change方法。
changeSpeed = 200
def changeColor():
rgb = colorsys.hsv_to_rgb(*hsv)
hexCode = getHexCode(rgb)
canvas.config(background = hexCode)
hsv[0]+=0.01
root.after(changeSpeed,changeColor)
root.after(changeSpeed, changeColor)
(已编辑)
以前的两个问题是 root.winfo_width()
和 root.winfo_height()
,以及全屏显示边框。
要解决第一个问题,我们必须以某种方式更新根对象,因为默认情况下它是 1x1。为此,我们可以做的是创建 Canvas
对象,然后更新它。看起来像这样:
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0) #Makes a canvas with a white coloured background
canvas.pack()
canvas.update()
canvas.config(width = root.winfo_width(), height = root.winfo_height())
第二个问题也通过使 canvas 对象具有特定属性 highlightthickness=0
来解决。如果您注意到,canvas 对象初始化现在是:
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0)
另一件我认为有用的事情是如果一个按钮关闭程序。我使用以下命令将 "Escape" 键绑定到关闭:
def quit(event):
root.destroy()
root.bind("<Escape>", quit)
作为一个完整的程序,它看起来像这样:
import colorsys
from tkinter import Tk, Canvas
hsv = [0,1,0.8]
changeSpeed = 200
root = Tk()
root.attributes("-fullscreen",True)
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0) #Makes a canvas with a white coloured background
canvas.pack()
canvas.update()
canvas.config(width = root.winfo_width(), height = root.winfo_height())
def getHexCode(rgb):
r = hex(int(rgb[0]*255))[2:]
if len(r) < 2:
r = "0"+r
g = hex(int(rgb[1]*255))[2:]
if len(g) < 2:
g = "0"+g
b = hex(int(rgb[2]*255))[2:]
if len(b) < 2:
b = "0"+b
return "#" + r + g + b
def changeColor():
rgb = colorsys.hsv_to_rgb(*hsv)
hexCode = getHexCode(rgb)
canvas.config(background = hexCode)
hsv[0]+=0.01
root.after(changeSpeed,changeColor)
def quit(event):
root.destroy()
root.after(changeSpeed, changeColor)
root.bind("<Escape>", quit)
root.mainloop()
您可以在此更改的一些变量是 changeSpeed、原始 hsv 列表以及添加到色相中的 0.01 每次增加
我正在尝试制作一个全屏显示单一颜色的程序。这个想法是在大屏幕上使用它来创造房间的环境,屏幕在一定时间后会从一种颜色变为另一种颜色。
全屏显示颜色没有问题,但我怎样才能顺利地改变所说的颜色?
对于全屏显示,我使用了与屏幕大小相同的 Tkinter window:imagesprite = canvas.create_image(w/2, h/2, image=image)
其中 image
是某种颜色。但是要更改颜色,我需要使用 root.after(2000, root.destroy)
破坏 window,然后创建一个新的。这并不流畅,因为可以看到短暂的桌面。
如何随时随地更改 Tkinter window 中显示的图像,或者,如何关闭一个 window 并顺利打开另一个?
您可以选择为 Canvas 对象设置背景而不是使用图像。这是具有单一颜色背景的最少代码。
from tkinter import Tk, Canvas
root = Tk()
root.attributes("-fullscreen",True)#Makes the window fullscreen
canvas = Canvas(root, width=root.winfo_width(),height=root.winfo_height(), background="red") #Makes a canvas with a red coloured background
#The width and height of the Canvas are taken from the root object
canvas.pack()
root.mainloop()
从这里开始,无需不断删除 window,只需更改 Tkinter 小部件的属性即可。这是使用 config 方法完成的。
canvas.config(background="green")
tkinter 的一大优点是你可以给它一个颜色的十六进制代码,它会使用它来绘制。它需要采用如下格式的字符串:
"#RRGGBB"
其中每组是一个从 0 到 FF 的十六进制数。
考虑到这一点,您可以增加每帧的十六进制数,或者增加两种颜色之间所需的任意帧数。要获得良好的过渡效果,您可能需要使用 Hue、Saturation、Value (HSV) 颜色,并且只更改 Hue 值。
您可以将 HSV 存储在列表中:
hsv = [0,0.7,0.7]
要转换,首先要转换为 0 到 255 RGB,然后再转换为十六进制。
import colorsys
rgb = colorsys.hsv_to_rgb(*hsv) #Uses list unpacking to give it as arguments
接下来,您使用 rgb 并将其转换为 Hexcode 格式。
def getHexCode(rgb):
r = hex(int(rgb[0]*255))[2:] #converts to hexadecimal
#With the hex() function, it returns a number in "0xFE" format (0x representing hex).
#To ignore this, we can take the substring using [2:]
if len(r) < 2: #If the value is a 1-digit number, then we want to add a zero at the front for hexcode form
r = "0"+r
g = hex(int(rgb[1]*255))[2:]
if len(g) < 2:
g = "0"+g
b = hex(int(rgb[2]*255))[2:]
if len(b) < 2:
b = "0"+b
return "#" + r + g + b
最后,我们真正调用了change方法。
changeSpeed = 200
def changeColor():
rgb = colorsys.hsv_to_rgb(*hsv)
hexCode = getHexCode(rgb)
canvas.config(background = hexCode)
hsv[0]+=0.01
root.after(changeSpeed,changeColor)
root.after(changeSpeed, changeColor)
(已编辑)
以前的两个问题是 root.winfo_width()
和 root.winfo_height()
,以及全屏显示边框。
要解决第一个问题,我们必须以某种方式更新根对象,因为默认情况下它是 1x1。为此,我们可以做的是创建 Canvas
对象,然后更新它。看起来像这样:
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0) #Makes a canvas with a white coloured background
canvas.pack()
canvas.update()
canvas.config(width = root.winfo_width(), height = root.winfo_height())
第二个问题也通过使 canvas 对象具有特定属性 highlightthickness=0
来解决。如果您注意到,canvas 对象初始化现在是:
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0)
另一件我认为有用的事情是如果一个按钮关闭程序。我使用以下命令将 "Escape" 键绑定到关闭:
def quit(event):
root.destroy()
root.bind("<Escape>", quit)
作为一个完整的程序,它看起来像这样:
import colorsys
from tkinter import Tk, Canvas
hsv = [0,1,0.8]
changeSpeed = 200
root = Tk()
root.attributes("-fullscreen",True)
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0) #Makes a canvas with a white coloured background
canvas.pack()
canvas.update()
canvas.config(width = root.winfo_width(), height = root.winfo_height())
def getHexCode(rgb):
r = hex(int(rgb[0]*255))[2:]
if len(r) < 2:
r = "0"+r
g = hex(int(rgb[1]*255))[2:]
if len(g) < 2:
g = "0"+g
b = hex(int(rgb[2]*255))[2:]
if len(b) < 2:
b = "0"+b
return "#" + r + g + b
def changeColor():
rgb = colorsys.hsv_to_rgb(*hsv)
hexCode = getHexCode(rgb)
canvas.config(background = hexCode)
hsv[0]+=0.01
root.after(changeSpeed,changeColor)
def quit(event):
root.destroy()
root.after(changeSpeed, changeColor)
root.bind("<Escape>", quit)
root.mainloop()
您可以在此更改的一些变量是 changeSpeed、原始 hsv 列表以及添加到色相中的 0.01 每次增加