tkinter消息框未在Windows任务栏上显示

时间:2017-08-17 05:53:43

标签: python windows python-3.x tkinter

我正在编写一个Python应用程序,并希望messagebox通知用户一个错误,它在Linux中的行为(在Mint和Ubuntu上测试),但在Windows上它不会创建一个任务栏上的应用程序,因此它会丢失。我也可以把它贴在前面,但这也有点令人讨厌。以下是我正在使用的内容:

from tkinter import Tk, messagebox

root = Tk()
messagebox.showerror("Oh please work oh please work oh please", "Show up on taskbar! ... *sigh")
root.withdraw()

2 个答案:

答案 0 :(得分:1)

首先,让我们详细说明 transient 窗口在root-toplevel示例中的含义。

默认情况下,Toplevel显示为非瞬态,但是,由于transient方法,我们能够解决这个问题。 这是一个片段:

import tkinter as tk

root = tk.Tk()
tk.Label(root, text='root').pack()
top = tk.Toplevel(root)
tk.Label(top, text='toplevel').pack()
# uncomment to make top transient
# top.transient(root)
root.mainloop()

好的,现在我们对它有所了解,尤其是关于Windows上任务栏行为的事实。

但是解决方案呢?有一些,你的方法还可以,让我们稍微修改一下:

import tkinter as tk
import tkinter.messagebox as msg

root = tk.Tk()

if root._windowingsystem == 'win32':
    # windows showerror
    top = tk.Toplevel(root)
    top.iconify()
    msg.showerror("Oh please work oh please work oh please", "Show up on taskbar! ... *sigh", parent=top)
    top.destroy()
else:
    # non-windows showerror
    msg.showerror("Oh please work oh please work oh please", "Show up on taskbar! ... *sigh")

root.destroy()

如果你在tkinter的引导下爬行 - 你会发现parent参数不是真的可选,tkinterTk视为父母如果你通过None。但是我们可以使用dummy-Toplevel来提供它,因此我们的消息将 transient Toplevel而不是Tk实例。

另外,正如我在评论中所说,我们可以调用原生MessageBox

import tkinter as tk
import tkinter.messagebox as msg
import ctypes

MB_OK = 0x0
ICON_STOP = 0x10


root = tk.Tk()

# non-transient app-wide version
native_showerror = lambda: ctypes.windll.user32.MessageBoxW(0, "Oh please work oh please work oh please",
                                                            "Show up on taskbar! ... *sigh", MB_OK | ICON_STOP)
# transient version if we pass hWnd of the root window
native_showerror_transient = lambda: ctypes.windll.user32.MessageBoxW(root.winfo_id(),
                                                                      "Oh please work oh please work oh please",
                                                                      "Show up on taskbar! ... *sigh", MB_OK | ICON_STOP)

if root._windowingsystem == 'win32':
    # windows showerror
    root.update_idletasks()
    native_showerror()

else:
    # non-windows showerror
    msg.showerror("Oh please work oh please work oh please", "Show up on taskbar! ... *sigh")

root.mainloop()

虽然它并不算作为我的解决方法(我们不接受tkinter,我们做我们想做的事),它是某种重新发明的轮子,因为这个东西已经在引擎盖下实现了。但是,它在外观方面更灵活,但它不是你问题的重点。

答案 1 :(得分:0)

所以我发现的一个解决方法是取代取消根窗口,我只是将隐身或root设置为0,然后将其最小化以大大降低按下不可见退出按钮的已经很低的概率。然后我检查了操作系统是否运行Windows,如果没有,那么我撤回root。

from tkinter import Tk, messagebox
import sys

root = Tk()  # We need a main window
root.attributes('-alpha', 0.0)
root.wm_state('iconic')
if not sys.platform.lower().startswith("win"):
    root.withdraw()
messagebox.showerror("Oops!", "Sorry! Could not connect to the server!")
root.withdraw()

注意:Windows和Linux是我支持的唯一两个平台,但我猜测这也适用于Mac。如果您发现不同,请告诉我