简体   繁体   English

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

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

In Mac OS, the tkinter message boxes do NOT show different icons for different types of message box (other than warning).在 Mac OS 中,tkinter 消息框不会为不同类型的消息框显示不同的图标(警告除外)。 The error, info, and question icons are all the "Python Spaceship" icon and not specific to errors, info, or questions.错误、信息和问题图标都是“Python Spaceship”图标,并不特定于错误、信息或问题。 See attached files starting with "Screen Shot ..."查看以“Screen Shot ...”开头的附件

In Windows, the message boxes show context sensitive icons.在 Windows 中,消息框显示上下文相关图标。 See attached file WindowsMessageBoxOutput.jpg见附件 WindowsMessageBoxOutput.jpg

How do I get the context sensitive icons to load on Mac OS?如何在 Mac OS 上加载上下文相关图标?

The code I used for generating/showing the message boxes is the following:我用于生成/显示消息框的代码如下:

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()

Note: I tried various options to try and generate message boxes with icons (hence the various calls in the code above).注意:我尝试了各种选项来尝试生成带有图标的消息框(因此上面代码中的各种调用)。

Environment环境

I'm running with the following on Mac OS:我在 Mac OS 上运行以下命令:

  • Mojave 10.14.6莫哈韦 10.14.6
  • Python 3.7.5 Python 3.7.5
  • tkinter 8.5 tkinter 8.5

Images:图片:

MacOS 消息框 Windows 消息框

I can confirm that this happens on MacOS at least in Big Sur in Python 3.9.9 and 3.10.4.我可以确认这至少在 Python 3.9.9 和 3.10.4 的 Big Sur 中发生在 MacOS 上。

The only fix I found was to - only in macos!我发现的唯一解决方法是 - 仅在 macos 中! -change the app icon before the call to the messagebox as suggested in How to correct picture tkinter messagebox tkinter on macos and back after the call to messagebox. - 按照如何在 macos 上更正图片 tkinter 消息框 tkinter中的建议,在调用消息框之前更改应用程序图标,并在调用消息框后返回。

I've tried to wrap this behaviour in a python decorator 'if_mac_set_icon' for a clean appearance.我试图将此行为包装在 python 装饰器“if_mac_set_icon”中以获得干净的外观。 The program needs some supplied images in a folder 'images'.该程序需要一些在“图像”文件夹中提供的图像。 See the code for details.有关详细信息,请参阅代码。 Tested on Big Sur and Windows (decorator does nothing there).在 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, I see the same behavior on: FWIW,我在以下位置看到相同的行为:

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

Works as expected on Windows & Linux and I can override the default messagebox icon type with the "icon" parameter.在 Windows 和 Linux 上按预期工作,我可以使用“icon”参数覆盖默认的消息框图标类型。

Looks like it's been an issue for some time now: Why can't I change the icon on a tkMessagebox.askyesno() on OS X?看起来这个问题已经有一段时间了: 为什么我不能在 OS X 上更改 tkMessagebox.askyesno() 上的图标?

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

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