我编写了一个模拟“瀑布式”显示的短脚本,其中通过一个较小的窗口滚动显示一个很长的图像。我的程序将两个图像并排滚动:第一个图像未校准,第二个图像是第一个图像的校准版本。实际上,这些图像是逐行生成的,并且(大致)实时显示。我的模拟器不是实时的,只是从数据文件中读取两个图像
我是tkinter的新手,只是想通过在线教程制作一个简单的GUI。GUI窗口均为300x480-两个图像为~10000x480彩色图像,同时在GUI窗口中滚动
脚本基本上按预期运行,直到结束
两个映像完成滚动后,在Spyder中,内核死亡并重新启动。除了“内核死机,重新启动”之外,没有给出任何错误。从命令行运行我的程序,在脚本显示完整图像后,我得到错误“分配位图失败”。我假设“未能分配位图”是导致Spyder中内核死亡的原因,这是我在Tk中做的错误
以下是我的(伪)代码:
import tkinter
from PIL import Image, ImageTk
import numpy as np
import sys
lines = <length of image along one dimension>
extractedImageArray = <uncalibrated 24-bit image as array of dimension [lines, 480, 3]>
calibratedImageArray = <calibrated 24-bit image as array of dimension [lines, 480, 3]>
im1 = np.zeros((300,480,3), dtype=np.uint8)
im2 = np.zeros((300,480,3), dtype=np.uint8)
root = tkinter.Tk()
root.geometry('960x350+0+0')
root.title('Waterfall Emulator')
root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=1)
root.grid_rowconfigure(0,weight=1)
root.grid_rowconfigure(1,weight=0)
root.button = tkinter.Button(root,text='Quit',command=root.destroy)
root.button.grid(row=1, column=0, columnspan=2)
for i in range(lines):
try:
im1 = np.vstack((im1[1:,:,:],extractedImageArray[i,:,:].reshape((1,480,3))))
leftImage=ImageTk.PhotoImage(Image.fromarray(im1))
leftImageLabel = tkinter.Label(image=leftImage)
leftImageLabel.grid(row=0, column=0, padx=4, pady=4)
# Store a reference to a PhotoImage object, to avoid it
# being garbage collected! This is necesary to display the image!
leftImageLabel.image = leftImage
im2 = np.vstack((im2[1:,:,:],calibratedImageArray[i,:,:].reshape((1,480,3))))
rightImage=ImageTk.PhotoImage(Image.fromarray(im2))
rightImageLabel = tkinter.Label(image=rightImage)
rightImageLabel.grid(row=0, column=1, padx=4, pady=4)
# Store a reference to a PhotoImage object, to avoid it
# being garbage collected! This is necesary to display the image!
rightImageLabel.image = rightImage
root.update()
except:
sys.exit()
root.mainloop()
程序基本上做了我需要的事情,但令人恼火的是,内核在最后死了,而没有一个干净的出口。我想这个错误一定是因为我对tkinter缺乏经验
为什么在脚本执行后内核会死亡
=======================================================================================
增加:
为了完整起见,在Martineau的解决方案之后,我修改了我的脚本:我将按钮创建拉到循环之外,现在只更新标签
<--snip-->
root.button = tkinter.Button(root,text='Quit',command=root.destroy)
root.button.grid(row=1, column=0, columnspan=2)
leftImage=ImageTk.PhotoImage(Image.fromarray(im1))
leftImageLabel = tkinter.Label(image=leftImage)
leftImageLabel.grid(row=0, column=0, padx=4, pady=4)
rightImage=ImageTk.PhotoImage(Image.fromarray(im2))
rightImageLabel = tkinter.Label(image=rightImage)
rightImageLabel.grid(row=0, column=1, padx=4, pady=4)
for i in range(lines):
try:
im1 = np.vstack((im1[1:,:,:],extractedImageArray[i,:,:].reshape((1,480,3))))
leftImage=ImageTk.PhotoImage(Image.fromarray(im1))
leftImageLabel.configure(image=leftImage)
# Store a reference to a PhotoImage object, to avoid it
# being garbage collected! This is necesary to display the image!
leftImageLabel.image = leftImage
im2 = np.vstack((im2[1:,:,:],calibratedImageArray[i,:,:].reshape((1,480,3))))
rightImage=ImageTk.PhotoImage(Image.fromarray(im2))
rightImageLabel.configure(image=rightImage)
# Store a reference to a PhotoImage object, to avoid it
# being garbage collected! This is necesary to display the image!
rightImageLabel.image = rightImage
您正在创建~10000
Label
个小部件,每个小部件都有一个关联的图像,这需要占用大量内存你真的不需要一次全部使用,因为你的程序只在一个方向上“滚动”——这意味着你应该能够显著减少改变与固定的、相对较少的
Label
个数相关的图像所需的内存量您可以使用^{} 方法更改现有的
Label
小部件相关问题 更多 >
编程相关推荐