【发布时间】:2017-12-07 10:27:24
【问题描述】:
有没有办法从tkinter.Label 实例中获取tkinter.PhotoImage 对象?我知道有this question,它有一个部分令人满意的答案,但我真的需要一个PhotoImage 对象:
>>> import tkinter as tk
>>>
>>> root = tk.Tk()
>>>
>>> image1 = tk.PhotoImage(file="img.gif")
>>> image2 = tk.PhotoImage(file="img.gif")
>>>
>>> label = tk.Label(root, image=image1)
>>> label._image_ref = image1
>>> label.cget("image") == image2
False
是否有一个函数可以让我从pyimage 字符串中获取图像对象? IE。一个从label.cget("image")获得?
答案是,apparantly,你不能。最接近的方法是获取图像源(文件或数据)并检查(可能通过散列)两个图像是否相同。 tkinter.PhotoImage没有实现__eq__,所以你不能只比较两个图像以获得相同的数据。这是解决问题的最后一个示例(大部分):
import hashlib
import os
import tkinter as tk
_BUFFER_SIZE = 65536
def _read_buffered(filename):
"""Read bytes from a file, in chunks.
Arguments:
- filename: str: The name of the file to read from.
Returns:
- bytes: The file's contents.
"""
contents = []
with open(filename, "rb") as fd:
while True:
chunk = fd.read(_BUFFER_SIZE)
if not chunk:
break
contents.append(chunk)
return bytes().join(contents)
def displays_image(image_file, widget):
"""Check whether or not 'widget' displays 'image_file'.
Reading an entire image from a file is computationally expensive!
Note that this function will always return False if 'widget' is not mapped.
This doesn't work for images that were initialized from bytes.
Arguments:
- image_file: str: The path to an image file.
- widget: tk.Widget: A tkinter widget capable of displaying images.
Returns:
- bool: True if the image is being displayed, else False.
"""
expected_hash = hashlib.sha256(_read_buffered(image_file)).hexdigest()
if widget.winfo_ismapped():
widget_file = widget.winfo_toplevel().call(
widget.cget("image"), "cget", "-file"
)
if os.path.getsize(widget_file) != os.path.getsize(image_file):
# Size differs, the contents can never be the same.
return False
image_hash = hashlib.sha256(
_read_buffered(widget_file)
).hexdigest()
return image_hash == expected_hash
【问题讨论】:
-
您将其存储为
label._image_ref,不是吗?因此链接的答案适用于label._image_ref.cget('file')。但是为什么你声称它是部分令人满意的呢?在您的情况下,平等始终是False,因为它与image1 == image2相同(PhotoImage没有__eq__方法)。 -
我正在编写一个模拟 GUI 测试库,我想要一种方法来检查当前是否正在显示图像。我不能假设人们会保留对图像的引用。我不明白为什么
PhotoImage__eq__实现不处理视觉相似性,但这是一个不同的问题。 -
PhotoImage对象没有定义__eq__方法,所以它们继承了默认的方法,这意味着做image1 == image2相当于image1 is image2,所以它会返回False,因为它们不是同一个对象,即使它们包含相同的图像数据。 -
嗯,这很荒谬,但我可以希望解决这个问题。
-
@Coal_,还有
> I can't assume people will keep a reference to the image.。为什么你不能?我可能是错的,但这是必须的,因为任何人都应该保留参考。
标签: python image user-interface tkinter