2017-08-17 74 views
1

我正在編寫一個Python應用程序,並希望messagebox通知用戶有錯誤,並且它在Linux中的行爲方式(在Mint和Ubuntu上測試),但是在Windows不會在任務欄上創建應用程序,因此它會丟失。我也可以堅持到前面,但這也有點令人討厭。這裏就是我的工作:tkinter messagebox不顯示在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

這樣的行爲,你想知道的是瞬態窗口,thoose共享任務欄的位置。在Windows上,您可以將'tk_messageBox'作爲本地'MessageBox'函數的包裝器,默認情況下這是一個瞬態和模式窗口。如果你希望它在任務欄上是一個獨立的東西 - 你可以通過內置的'ctypes'手動調用它作爲非瞬態。 – CommonSense

+0

@CommonSense聽起來像是要走的路!不幸的是,我不太瞭解ctypes或者如何在MessageBox中創建一個包裝器。我現在正在研究它,但是如果你想給我一些代碼讓我開始,我會很樂意接受一個工作的答案! – MANA624

回答

0

首先讓我們來詳細說明什麼瞬態窗口是根目錄示例。

默認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任務欄上的行爲的事實。

但是解決方案呢?這裏也有一些,你的做法是好的,讓我們修改它littlebit:

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填充它,因此我們的消息將是瞬態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的,我們做什麼我們希望這樣做),這是某種重新發明的方式,因爲這些東西已經在引擎蓋下實施了。然而,從外觀來看它更加靈活,但這不是你問題的一個要點。

+0

對不起,花了我很長時間才接受 - 學校發生了!無論如何,這給了我正在尋找的行爲。我可以在以後看看爲什麼 – MANA624

0

所以一個變通,我發現了,而不是退出根窗口,我剛纔設置的隱形或根爲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。請讓我知道,如果你發現不同

相關問題