在 Mac OS 上设置 tkinter 图标

Posted

技术标签:

【中文标题】在 Mac OS 上设置 tkinter 图标【英文标题】:Set tkinter icon on Mac OS 【发布时间】:2019-03-20 11:15:37 【问题描述】:

我正在尝试更改出现在 Mac OS 的 tk 应用程序上的图标。我上次检查此代码适用于 Windows。目标是让此解决方案在所有平台上都能正常工作。

root = tk.Tk()
app = Application(master=root)

app.master.iconbitmap("my_icon.ico")

app.mainloop()

代码正在为 .pdf 文件添加默认图标,这不是我想要的。 my_icon.ico 的路径是正确的。为什么这不适用于 Mac OS?有没有可以跨平台工作的终极解决方案?

【问题讨论】:

【参考方案1】:

根据tk tcl 文档,您可能想尝试wm iconphoto。看来它可能支持 OSX,并且还提到将文件设置为 512x512 左右以便在 MAC 中平滑渲染。

我没有 MAC,所以我无法对此进行测试,但可以试一试,如果有帮助,请告诉我。

更新:

正如@l'L'l 指出的,您可能想尝试root.iconphoto(True, img)。由于没有 Mac,我无法自己测试。

import tkinter as tk

root = tk.Tk()
img = tk.Image("photo", file="icon.gif")
# root.iconphoto(True, img) # you may also want to try this.
root.tk.call('wm','iconphoto', root._w, img)

root.mainloop()

这是来自documentation here的相关文字:

wm iconphoto 窗口?-默认?图像1 ?图像2 ...?设置标题栏 基于命名照片图像的窗口图标。如果 -default 是 指定,这也适用于所有未来创建的顶层。 图像中的数据是拍摄时的快照 调用。如果稍后更改图像,则不会反映到 标题栏图标。接受多个图像以允许不同 要提供的图像尺寸(例如,16x16 和 32x32)。窗户 经理可以将提供的图标缩放到适当的大小。在 Windows 上, 图像被打包到 Windows 图标结构中。这会 覆盖指定给 wm iconbitmap 的 ico,反之亦然。

在 X 上,图像被排列到 _NET_WM_ICON X 属性中,该属性 大多数现代窗口管理器都支持。可能存在 wm 图标位图 同时地。建议使用不超过2个图标, 首先放置较大的图标。

在 Macintosh 上,调用的第一个图像被加载到 OSX 原生图标中 格式,并成为对话框、Dock 和 其他情况。在脚本级别,该命令将只接受 传入参数的第一张图片作为对多张图片的支持 macOS 上的尺寸/分辨率超出了 Tk 的范围。开发者应该 使用他们可以支持的最大图标(最好是 512 像素) 确保在 Mac 上流畅渲染。

我确实在 Windows 上对此进行了测试,以确保它至少可以在那里工作。我用了一张蓝色的方形图片来测试。

如果上述文档是准确的,它也应该适用于 MAC。

【讨论】:

_tkinter.TclError: couldn't recognize data in image file "icon.ico" 我认为问题在于文件类型.ico 而不是将文件添加到 tkinter 的方法。 @Jake 我没有使用 .ico 文件。 ico 仅适用于 Windows。 Linux 也有自己的文件类型。试试 gif 文件,看看效果如何。 是否有可以跨平台工作的文件类型?我想避免做类似if platform == windows: .icoif platform == mac: .gif .... @Jake 对于这种方法,您实际上并没有使用 ICON 文件。这就是 gif 在这里工作的原因。所以gif 将或应该在所有系统上工作。 实际上这种(古老的)技术似乎不适用于macOS(它使用X11 作为窗口管理器)。在此类窗口上更改title 属性非常简单,但是,在Mac 上,无论tkinter 指向一个图标,该窗口始终使用默认的X11 图标。作为旁注,不要为图标调用tk,而应该只调用root.iconphoto(True, img)...【参考方案2】:

如果您使用的是 Mac OS,则必须使用 .icns 图像而不是 .ico 图像。

你可以使用:

from tkinter import Tk
from platform import system

platformD = system()
if platformD == 'Darwin':

    logo_image = 'images/logo.icns'

elif platformD == 'Windows':

    logo_image = 'images/logo.ico'

else:

    logo_image = 'images/logo.xbm'

root = Tk()
root.title("My App")
root.iconbitmap(logo_image)
root.resizable(0, 0)
root.mainloop()

【讨论】:

【参考方案3】:

重要提示:这种方法很长,而且手头的任务需要做很多工作。但是,它确实带来了一些不相关的好处。请注意,可能有更好的方法,但这会起作用。 无论如何,继续前进....

你可以使用py2app。

Py2app 会将您的程序变成.app,这意味着它作为应用程序运行(因为它是)。当使用tkinter 时,这通常是您最终想要的,因为 GUI 通常会变成应用程序以方便使用。您可以阅读 py2app 文档 here,或阅读非官方但更易于理解(在我看来)的教程 here。过程中我也会总结一下。

首先安装py2app: 在命令提示符中输入:

sudo pip install -U py2app

如果成功,你应该得到py2app。 如果没有,一个问题可能是您没有pip。你可以用另一个命令下载它:

sudo easy_install pip

第一步: 在同一个字典中创建一个名为 setup.py 的文件 作为程序。

第二步: 将其放入文件中。

from setuptools import setup

#APP would be the name of the file your code is in.
APP = ['example.py']
DATA_FILES = []
#The Magic is in OPTIONS.
OPTIONS = 
    'argv_emulation': False,
    'iconfile': 'app.icns', #change app.icns to the image file name!!!
    

setup(
    app=APP,
    name='Your app’s name', #change to anything
    data_files=DATA_FILES,
    options='py2app': OPTIONS,
    setup_requires=['py2app'],
)

第 3 步: 然后在文件所在的字典中打开 bash 终端并输入以下命令:

python setup.py py2app -A

-A 使应用程序响应代码中的更新,但使应用程序不可共享。完成开发后,重新运行命令,这次没有-A,如下所示:

python setup.py py2app

注意:对于 python 3 py2app,您可能需要使用命令 python3 setup.py py2... 而不是 python setup.py py2...

第 4 步: 导航到the dictionary your code is in/dist。在该文件夹中将是您的应用程序。 (dist 文件夹应该在您运行命令时在第三步中创建)

对于windows用户:py2app不是应该使用的,而是使用py2exe。

【讨论】:

我不明白这将如何解决图标不出现的原始问题。 这将创建自己的图标,删除 tkinter 默认值。我忘了指定如何更改py2app 默认图像,现在正在编辑... 请查看编辑后的答案。抱歉,我忘了包括图像更改。 ;) 更改在第 2 步,即'iconfile': 'app.icns' 这是一个独立应用程序的解决方案。 OP 只想在 IDE 执行代码期间更改窗口左上角的图标。 @Mike - SMT 是的,但是大多数 tkinter 程序无论如何都会变成的独立应用程序有自己的徽标。这创建一个独立的应用程序,但它也将解决他的问题,即设置图标。它的副作用可能不是最好的答案,但副作用可能还是有帮助的。答案是一样的。

以上是关于在 Mac OS 上设置 tkinter 图标的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Mac OS 上使用 Tkinter 获取黑色文件对话框?

删除 Tkinter 窗口上的 TK 图标

使用 Tkinter 和 Python 在 Mac OS X 中进行惯性滚动

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

Tkinter 窗口专注于 Mac OS X

Tkinter 将焦点设置在 Entry 小部件上