簡體   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