删除 Tkinter 窗口上的 TK 图标

Posted

技术标签:

【中文标题】删除 Tkinter 窗口上的 TK 图标【英文标题】:Removing the TK icon on a Tkinter window 【发布时间】:2010-10-07 16:41:03 【问题描述】:

如何从窗口的标题栏中删除 tkinter 图标

【问题讨论】:

【参考方案1】:

在 Windows 上

第一步:

使用图标编辑器或rw-designer 之类的网站创建透明图标。另存为transparent.ico

第二步:

from tkinter import *

tk = Tk()
tk.iconbitmap(default='transparent.ico')
lab = Label(tk, text='Window with transparent icon.')
lab.pack()
tk.mainloop()

在 Unix 上

类似的东西,但使用xbm 图标。

【讨论】:

与其创建一个图标,您只需谷歌“空白图标”并下载一个。例如:iconspedia.com/icon/blank-icon-44576.html @MarredCheese 是的,这也是一个选项,但是您必须遵守创建图标的设计师的许可详细信息。不过,它们应该不会太糟糕,所以这是个好主意。 最好的解决方案实际上是Dario's answer below,您可以在其中将透明图标嵌入到代码中,因此您的代码库中不必有额外的文件。【参考方案2】:

类似于接受的答案(缺点是更丑):

import tkinter
import tempfile

ICON = (b'\x00\x00\x01\x00\x01\x00\x10\x10\x00\x00\x01\x00\x08\x00h\x05\x00\x00'
        b'\x16\x00\x00\x00(\x00\x00\x00\x10\x00\x00\x00 \x00\x00\x00\x01\x00'
        b'\x08\x00\x00\x00\x00\x00@\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x01\x00\x00\x00\x01') + b'\x00'*1282 + b'\xff'*64

_, ICON_PATH = tempfile.mkstemp()
with open(ICON_PATH, 'wb') as icon_file:
    icon_file.write(ICON)

tk = tkinter.Tk()
tk.iconbitmap(default=ICON_PATH)
label = tkinter.Label(tk, text="Window with transparent icon.")
label.pack()

tk.mainloop()

它只是动态创建文件,因此您不必随身携带额外的文件。使用相同的方法,您还可以为 Unix 制作一个“.xbm”图标。

编辑:感谢@Magnus Hoff,ICON 可以进一步缩短:

import base64, zlib

ICON = zlib.decompress(base64.b64decode('eJxjYGAEQgEBBiDJwZDBy'
    'sAgxsDAoAHEQCEGBQaIOAg4sDIgACMUj4JRMApGwQgF/ykEAFXxQRc='))

【讨论】:

你是怎么得到那个格式的 'ICON = (...' 的?我在挣扎...***.com/questions/29507890/… 这样做很痛苦。我使用了@Stobor 在他的回答中提到的rw-designer 并生成了一个透明的 .ico 文件。然后我打开二进制文件并将数据复制/粘贴到我的 python 程序中。我注意到有很多重复,所以我把它缩短了一些——因此是b'\x00'*1282 + b'\xff'*64。如果您查看 .ico 格式规范,可能会进一步简化,但这对于我正在做的事情来说已经足够了。 您可以使用BitmapImagePhotoImage 类来转换字符串,而无需创建临时文件。 @PeterWood 当我使用BitmapImage 类运行tk.iconbitmap(default=ICON_PATH) 时得到_tkinter.TclError: bitmap "pyimage1" not defined,当我尝试创建PhotoImage 对象时得到_tkinter.TclError: couldn't recognize image data【参考方案3】:

根据之前的回复,我使用了这个解决方案:

from PIL import ImageTk
import zlib,base64
import Tkinter

icon=zlib.decompress(base64.b64decode('eJxjYGAEQgEBBiDJwZDBy'
'sAgxsDAoAHEQCEGBQaIOAg4sDIgACMUj4JRMApGwQgF/ykEAFXxQRc='))
root=Tkinter.Tk()
image=ImageTk.PhotoImage(data=icon)
root.tk.call('wm', 'iconphoto', root._w, image)
root.mainloop()

【讨论】:

这种方法的好处是它在内存中完成,不需要高清写入【参考方案4】:

据我所知,最接近“空白”图标的是使用与窗口标题栏颜色相同的图标。但是话又说回来,很多用户使用不同的颜色主题,所以它不会很好。

但是,如果您使用 py2exe,您可以使用 Resource Hacker 之类的东西来交换图标。但是在python程序文本状态下,你能做的最好的就是替换。类似于 Jar 文件如何使用 java 图标,tkinter 应用程序将具有 TK 图标。毕竟......就像java一样,您的应用程序正在由中间程序翻译。由于另一个程序正在运行您的代码,因此您必须修改该其他程序。幸运的是,python/tk 在图标方面比 JVM 更灵活一点,因此您可以替换图标。但目前还不能完全删除它。

-约翰

【讨论】:

【参考方案5】:

通过利用Tkinter.PhotoImage 对处理.gif 图像的内置支持来替代@ubomb 添加自定义图像的解决方案。

来自文件:

icon = Tkinter.PhotoImage(file="logo.gif")

来自base64:

gif_base64_string = """ R0lGODdhEAAQAIcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0NDQ4O Dg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8fHyAgICEh ... 4B8AAP9Ci/4HoLTpfwD+qV4NoHVAADs= """

icon = Tkinter.PhotoImage(data=gif_base64_string)

访问下面提到的链接了解更多详情: //effbot.org/tkinterbook/photoimage.htm

【讨论】:

【参考方案6】:

更新:

稍作修改的代码(try 子句而不是 if TkVersion)在以下位置生成一个透明(否)图标:

Linux (Mint 18.1)、Python 2.7

Linux (Mint 18.1)、Python 3.5.1

Windows 10、Python 2.7.13

它会在以下位置产生一个黑色图标(不起作用):

Windows 8.1、Python 3.6

一个相当老的问题,但解决方案对我不起作用。我找到了一个部分简单的解决方案,还有一个我自己的后续问题。

部分解决方案(Tk 8.5,见下文)——使用 PhotoImage 的blank() 方法:

from Tkinter import *

root=Tk()

icon=PhotoImage(height=16, width=16)
icon.blank()

root.tk.call('wm', 'iconphoto', self.master._w, icon)

root.mainloop()

在 Python 2.7、Windows 10 上,这可以正常工作,为您的新应用生成所需的“无图标”。

但是,在 Python 3.6、Win 8.1 上,这会阻塞 GUI,我认为这与较新的 Tk 8.6 有关,尽管我发现使用 wm_iconphoto() 的新 8.6 表示法在这种情况下确实通过了:

try:
    from tkinter import *
except:
    from Tkinter import * 

root=Tk()

#Identical for Py2.7/Tk8.5 and Py3.5/Tk8.6
icon=PhotoImage(height=16, width=16)
icon.blank()

#Picking a notaion based on Tk version to avoid jamming
try:
    root.wm_iconphoto('True', icon)   #New Tk 8.6 style        
else:
    #Jams Python 3.5 with Tk 8.6 on Windows
    root.tk.call('wm', 'iconphoto', self.master._w, icon)   



root.mainloop()

它会在 3.6 上生成一个黑色图标,而不是在 2.7/8.5 的情况下是透明图标。

可能有一种方法可以使用“透明度集”逐个设置像素透明 - http://wiki.tcl.tk/1449

但是,我不知道它是否可以通过 Tkinter 实现。上帝偏爱大胆的人,但轮到别人了?

更新问题:为什么这在 Py3.6/Windows 上不起作用?

【讨论】:

更新后的问题应作为新问题发布,并附上旧问题的链接。答案中发布的问题往往很长一段时间都不会被注意到...【参考方案7】:

最近,我在an old Ubuntu forum's post 找到了适用于 Linux 的解决方案。

该解决方案使用带有空白(填充零).xbm 文件的 iconbitmap 和 iconmask。

那么,首先,什么是 .xbm 文件?

.xbm 文件是纯文本(实际上是 C 代码!)图像格式,通常用于存储位图,数据存储为 2D 矩阵(二维数组,或数组数组) 使用 8 位(256 个可能的值,从 0 到 255)大小的元素,矩阵表示为单个一维数组加上定义其形状的值。

数据可以以任何方式解释,但通常被解释为单色/灰度图像。

图标位图

我们的第一个方法叫做iconbitmap,用于设置一个位图作为我们tkinter窗口的图标,我们可以输入一个.xbm文件的位置,它将表示为 单色/灰度图标,其中 .xbm 的像素/元素代表不同的灰度级别,记住像素/元素是 8 位值 在 0-255 范围内,因此值 0 将表示为黑色,255 将表示为白色,其他值将是这两个值之间的插值。

图标掩码

我们的第二种方法称为iconmask,这就是神奇之处,它用于将alpha/透明度值设置为窗口图标的像素, 我们可以输入 .xbm 文件的位置,.xbm 中值为 0 的元素将被设置为完全透明,我已经在 Debian 上使用 xfce4 和透明度值对其进行了测试 似乎没有在 0-255 范围内线性插值。

我们的解决方案

有了这些信息,我们可以通过以下方式使用 tkinter 创建一个透明图标:

import tkinter

tk = tkinter.Tk()

# Your file path has to start with an "@" otherwise the methods will raise an exception.
xbm_location = "@blank.xbm"
# Here we call the iconbitmap method with the xbm location, since it's a blank xbm (filled with zeroes) it will be represented as a black icon.
tk.iconbitmap(xbm_location)
# Here we call the iconmask method with xbm location, since it's a blank xbm (filled with zeroes) it will be represented as a fully transparent icon.
tk.iconmask(xbm_location)

还有我们的解决方案,我也在 Windows 上进行了测试,系统似乎只是忽略了 iconmask 方法,因此请坚持使用其他解决方案来处理您的 Windows 代码。

另一种可能的解决方案是使用方法 iconphoto 和从完全透明的 .gif 文件加载的 PhotoImage,甚至创建一个空白 PhotoImage as suggested by Jay, 但它似乎也不能在 Windows 上正常工作。

如何创建空白.xbm?

创建空白 .xbm 非常容易,只需下载 .xbm 文件,从头开始创建,或将图像转换为 .xbm,如果 .xbm 不是空白(用零填充),请打开 .xbm 在文本编辑器中,将数组中的所有值替换为“0x00”。

结论

就是这样,一个空白的 .xbm、iconbitmap 和 iconmask。现在您应该可以在 Linux 上的 tkinter 窗口中创建完全透明的图标了...

万岁!

【讨论】:

以上是关于删除 Tkinter 窗口上的 TK 图标的主要内容,如果未能解决你的问题,请参考以下文章

Python图形用户界面

设置窗口图标tkinter macosx

在 Mac OS 上设置 tkinter 图标

Tkinter 在 Mac 上的 Tk() 上不断崩溃

使用 Tkinter 在 GIF 中播放动画 [重复]

试图按下主页上的应答按钮但窗口冻结:Tkinter