我正在编写一个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()
答案 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
参数不是真的可选,tkinter
将Tk
视为父母如果你通过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。如果您发现不同,请告诉我