【发布时间】:2019-09-01 04:07:23
【问题描述】:
我需要一些关于如何处理这个项目的建议。多年前我有一些编程经验,但最近几周才开始接触 Python。
这个 Python 3 程序有一个 tkinter 屏幕,上面有 150 个图标。图标是标签小部件,根据从文本文件读入程序的设备状态显示三个 20x20 png 图形之一。每个图标每天都需要更换几次。
任何关于在这种情况下显示这些图标的方法的建议将不胜感激。
我已经尝试了几次。理想情况下,StringVar()/textvariable 类型的方法会很好(这对于更改标签中的文本非常有效),但我找不到类似的图像方法。只是一遍又一遍地将相同的标签推到屏幕上是行不通的,因为程序最终会“内存不足”崩溃。
编辑: 我已经使用键/值对解决了这个问题,因此每个循环都不会创建新标签。该方法适用于单个实例,但是一旦我将其放入此循环结构中,它就会崩溃并出现“TypeError: 'str' object does not support item assignment”。我创建了这个简单的例程,它反映了我在大型项目中遇到的问题。我怎样才能让它工作?
import tkinter as tk
import time
window = tk.Tk()
window.title("PiStatus")
window.geometry("500x500+0+0")
ct = 0
# You can use any small images for this, mine are 20x20 pixels.
pc_on_icon = tk.PhotoImage(file="1.png")
pc_active_icon = tk.PhotoImage(file="2.png")
pc_off_icon = tk.PhotoImage(file="0.png")
# This loop creates the base 15x10 grid of labels, each with a unique name.
for ypos in range(10):
for xpos in range(15):
label_name = "icon" + str(xpos) + "-" + str(ypos)
label_name = tk.Label(window, image=pc_on_icon)
label_name.grid(row=ypos, column=xpos)
while True:
# These statements cycle through the 3 images
if ct == 0:
turn = pc_off_icon
elif ct == 1:
turn = pc_on_icon
else:
turn = pc_active_icon
# This loop references each label giving it a different image each time around.
for ypos in range(10):
for xpos in range(15):
label_name = "icon" + str(xpos) + "-" + str(ypos)
label_name['image'] = turn # This is where the error occurs.
ct += 1
if ct == 3:
ct = 0
window.update()
window.mainloop()
【问题讨论】:
-
您好,欢迎来到 SO。我建议您提供您正在处理的代码示例,即使您正在寻求建议,它也可能有助于更好地理解上下文。
-
为所有状态创建标签,并且只使与当前设备状态对应的那些可见。
-
非常感谢丹。我还没有遇到自定义小部件。这种方法看起来很有趣,我需要一些时间来消化并将这种方法应用到我的代码中。我会告诉你进展如何。
-
没问题。您实际上并不需要
Frame派生类,您可以将所有 450 个标签推入一个列表并进行基本数学计算以计算正确的索引......这似乎是构建代码的更好方法. -
不幸的是,这看起来不适合丹。检查代码看起来每个循环仍在创建一个新的标签实例。我运行了一个小时,它在运行时消耗了 14M 的可用内存。我在树莓派上运行它,所以内存并不是那么大。完全披露,我没有加载 pil 模块,也不需要显示 png 文件,所以我从你的代码中删除了它。但我认为这不会影响这些结果。我希望它无需每天重新启动即可运行以释放内存。