繁体   English   中英

Mac OS 上的 Python TKinter 不显示消息框特定图标

[英]Python TKinter on Mac OS does not show message box specific icons

在 Mac OS 中,tkinter 消息框不会为不同类型的消息框显示不同的图标(警告除外)。 错误、信息和问题图标都是“Python Spaceship”图标,并不特定于错误、信息或问题。 查看以“Screen Shot ...”开头的附件

在 Windows 中,消息框显示上下文相关图标。 见附件 WindowsMessageBoxOutput.jpg

如何在 Mac OS 上加载上下文相关图标?

我用于生成/显示消息框的代码如下:

import tkinter as tk
import tkinter.messagebox as tkmb
from tkinter import Button

def show_message_boxes():
    tkmb.showinfo(title='Info Box', message='Info with info icon', icon='info')
    tkmb.showinfo(title='Info Box', message='Info with error icon', icon='error')
    tkmb.showinfo(title='Info Box', message='Info with question icon', icon='question')
    tkmb.showinfo(title='Info Box', message='Info with warning icon', icon='warning')

    tkmb.showinfo(title='Info Box', message='Info box with info icon', icon='info')
    tkmb.showerror(title='Error Box', message='Error box with default icon', icon='error')
    tkmb.showwarning(title='Warning Box', message='Warning box with default icon', icon='warning')

    tkmb.showinfo(title='Info Box', message='Info box with default icon')
    tkmb.showerror(title='Error Box', message='Error box with default icon')
    tkmb.showwarning(title='Warning Box', message='Warning box with default icon')

window = tk.Tk()

but = Button(window, text ='Click', command = show_message_boxes, width=20, height=10)
but.grid(row=0, column=0)

window.mainloop()

注意:我尝试了各种选项来尝试生成带有图标的消息框(因此上面代码中的各种调用)。

环境

我在 Mac OS 上运行以下命令:

  • 莫哈韦 10.14.6
  • Python 3.7.5
  • tkinter 8.5

图片:

MacOS 消息框 Windows 消息框

我可以确认这至少在 Python 3.9.9 和 3.10.4 的 Big Sur 中发生在 MacOS 上。

我发现的唯一解决方法是 - 仅在 macos 中! - 按照如何在 macos 上更正图片 tkinter 消息框 tkinter中的建议,在调用消息框之前更改应用程序图标,并在调用消息框后返回。

我试图将此行为包装在 python 装饰器“if_mac_set_icon”中以获得干净的外观。 该程序需要一些在“图像”文件夹中提供的图像。 有关详细信息,请参阅代码。 在 Big Sur 和 Windows 上测试(装饰器在那里什么都不做)。

from tkinter import Tk, Tcl, Button, messagebox, PhotoImage
from tkinter import ttk
import sys
"""
On MacOS Big Sur using Python 3.9.3:
- messagebox.showwarning() shows yellow exclamationmark with small rocket icon
- showerror(),askretrycancel,askyesno,askquestion, askyesnocancel
On MacOS BigSur using Python 3.10.4 same but with a folder icon instead 
of the rocket item. Tcl/Tk version is 8.6.12 """


# use a decorator with a parameter to add pre and postrocessing
# switching the iconphoto of the root/app see
# https://stackoverflow.com/questions/51530310/how-to-correct-picture-tkinter-messagebox-tkinter-on-macos
# decorator info: see https://realpython.com/primer-on-python-decorators/
def if_mac_set_icon(icon):
    def set_icon(icon):
     """ this function needs a folder 'images' with images with the below 
     names like app.png"""
        images = dict(
            app="app.png",
            info="exclamation.png",
            warning="exclamation.png",
            question="question.png",
            error="error.png"
        )
        img = PhotoImage(file=f"images/{images[icon]}")
        root.iconphoto(False, img)

    def decorator_func(original_func):
        def wrapper_func(*args, **kwargs):
            if sys.platform == "darwin":
                set_icon(icon)
            return original_func(*args, **kwargs)
            if sys.platform == "darwin":
                set_icon('app')  # restore app icon
        return wrapper_func
    return decorator_func


@if_mac_set_icon('warning')
def showwarning(*args, **kwargs):
    return messagebox.showwarning(*args, **kwargs)


@if_mac_set_icon('question')
def askquestion(*args, **kwargs):
    return messagebox.askquestion(*args, **kwargs)


@if_mac_set_icon('error')
def showerror(*args, **kwargs):
    return messagebox.showerror(*args, **kwargs)


@if_mac_set_icon('question')
def askretrycancel(*args, **kwargs):
    return messagebox.askretrycancel(*args, **kwargs)


@if_mac_set_icon('question')
def askyesno(*args, **kwargs):
    return messagebox.askyesno(*args, **kwargs)


root = Tk()

ttk.Button(root, text="Warningbox", command=showwarning).grid()
ttk.Button(root, text="Questionbox", command=askquestion).grid()
ttk.Button(root, text="Errorbox", command=lambda: askquestion(message="Error")).grid()

root.mainloop()

FWIW,我在以下位置看到相同的行为:

  • 操作系统 10.15.5
  • 蟒蛇 3.8.3
  • tkinter 8.6

在 Windows 和 Linux 上按预期工作,我可以使用“icon”参数覆盖默认的消息框图标类型。

看起来这个问题已经有一段时间了: 为什么我不能在 OS X 上更改 tkMessagebox.askyesno() 上的图标?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM