python - 如何在 tkinter 中替换背景图像?
问题描述
我有一个正在循环的脚本,一旦满足条件,就会将图像添加到我的 Tkinter 窗口中。我可以在 Tkinter 中添加和调整图像大小,但是当我通过 while 循环时,我想做的是替换图像(或者更确切地说,只是在前一个图像之上添加另一个图像)。然而,虽然Images
被重新定义为“greencar.jpg”,但实际图像并未发布在窗口中。
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
Images=()
class Example(Frame):
global Images
def __init__(self, master, *pargs):
Frame.__init__(self, master, *pargs)
self.image = Image.open(Images)
self.img_copy= self.image.copy()
self.background_image = ImageTk.PhotoImage(self.image)
self.background = Label(self, image=self.background_image)
self.background.pack(fill=BOTH, expand=YES)
self.background.bind('<Configure>', self._resize_image)
def _resize_image(self,event):
new_width = event.width
new_height = event.height
self.image = self.img_copy.resize((new_width, new_height))
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image = self.background_image)
def main():
global Images
x=0
root.update_idletasks()
while x<100000:
x+=1
if x == 500:
Images='mountain.jpg'
e = Example(root)
e.pack(fill=BOTH, expand=YES)
root.update_idletasks()
if x == 5000:
Images='greencar.jpg'
e = Example(root)
e.pack(fill=BOTH, expand=YES)
root.update_idletasks()
root = tk.Tk()
root.geometry('600x600')
main()
root.mainloop()
编辑:所以尝试 Saad 的解决方案效果非常好,但我试图通过实现几个函数和第二个循环来进一步扩展它。
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
Images= "mountain.jpg"
class Example(Frame):
def __init__(self, master, *pargs):
Frame.__init__(self, master, *pargs)
self.image = Image.open(Images)
self.img_copy= self.image.copy()
self.background_image = ImageTk.PhotoImage(self.image)
self.background = Label(self, image=self.background_image)
self.background.pack(fill=BOTH, expand=YES)
self.background.bind('<Configure>', self._resize_image)
def _resize_image(self,event):
new_width = event.width
new_height = event.height
self.image = self.img_copy.resize((new_width, new_height))
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image = self.background_image)
def change_image(self, file):
"""Change background image of the window."""
size = (self.winfo_width(), self.winfo_height())
self.image = Image.open(file).resize(size)
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image=self.background_image)
def add(x):
return x+3
def subtract(x):
return x-1
def check_image(x=0):
x=add(x)
if x >= 1000:
return # Break the loop
if x == 50:
e.change_image('mountain.jpg')
elif x == 500:
e.change_image('greencar.jpg')
print(x)
root.after(1, check_image,subtract(x))
def loop():
while True:
question=input('go again?')
if question == 'n':
break
check_image(x=0)
root = tk.Tk()
root.geometry('600x600')
e = Example(root)
e.pack(fill=BOTH, expand=YES)
loop()
root.mainloop()
所以我想要的是让用户再次通过循环的选项。所以我做了另一个函数来做到这一点。但是,check_image()
不再循环。它在第一次迭代时停止。如果我打破了我的时间loop()
(通过输入'n'),那么它将经历check_image()
迭代,但是,图像不再更新。总之,我好像又把程序弄坏了,但我不太明白为什么。
解决方案
您的代码有几个问题需要解决。
要替换图像,您必须每次都创建一个
PhotoImage
带有参数的新实例,然后。与您的函数一样,您只是在同一窗口中创建一个新的小部件。file='new_image.png'
self.background.configure(image=new_image_instance)
main
Example
我不建议
update_idletasks()
在while循环中使用整个while循环可以用after(ms, func, *args)
Tkinter的方法代替。def check_image(x=0): # Break the loop if x >= 100000: return if x == 500: e.change_image('mountain.jpg') elif x == 5000: e.change_image('greencar.jpg') root.after(1, check_image, x+1)
我认为最好只创建一个可以更改
Example
小部件图像的方法。def change_image(self, file): """Change background image of the window.""" size = (self.winfo_width(), self.winfo_height()) self.image = Image.open(file).resize(size) self.background_image = ImageTk.PhotoImage(self.image) self.background.configure(image=self.background_image)
完整代码:
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
Images= "image.png"
class Example(Frame):
def __init__(self, master, *pargs):
Frame.__init__(self, master, *pargs)
self.image = Image.open(Images)
self.img_copy= self.image.copy()
self.background_image = ImageTk.PhotoImage(self.image)
self.background = Label(self, image=self.background_image)
self.background.pack(fill=BOTH, expand=YES)
self.background.bind('<Configure>', self._resize_image)
def _resize_image(self,event):
new_width = event.width
new_height = event.height
self.image = self.img_copy.resize((new_width, new_height))
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image = self.background_image)
def change_image(self, file):
"""Change background image of the window."""
size = (self.winfo_width(), self.winfo_height())
self.image = Image.open(file).resize(size)
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image=self.background_image)
def check_image(x=0):
if x >= 100000: return # Break the loop
if x == 500:
e.change_image('mountain.jpg')
elif x == 5000:
e.change_image('greencar.jpg')
root.after(1, check_image, x+1)
root = tk.Tk()
root.geometry('600x600')
e = Example(root)
e.pack(fill=BOTH, expand=YES)
check_image()
root.mainloop()
推荐阅读
- postgresql - 错误:字符 67 处不存在列“none”
- javascript - 根据反应孩子的数量计算弹性基础
- ios - iOS端sigsegv(segv_access)小概率崩溃事件
- jquery - 匹配 div 中的部分文本,如果它匹配另一个 div 中的文本,则显示一个 span - jquery 和 javascript
- c++ - 下面的C++函数如何给下面的arm汇编函数传参?
- dictionary - 可靠的线程安全映射
- python - python解释器如何处理具有默认参数的函数定义的位置
- laravel - Laravel 7 重定向问题
- sql - 通过拆分和更改数据类型来比较两列
- c# - 将Image解压到内存并加载到picturebox中