我有一個運行一些嵌入式Python腳本的MFC應用程序。我正在嘗試使這個嵌入式腳本創建模態的對話框之一,但我沒有太大的成功。如何在tkinter中創建模態對話框?
任何人都可以指出做出模態對話的方式嗎?我是否需要使用windows函數或者只有Tk或Python函數足夠?
對於我GOOGLE了模樣的功能應該做的魔術以下組合,但他們似乎沒有工作,我期待的方式:
focus_set()
grab_set()
transient(parent)
我有一個運行一些嵌入式Python腳本的MFC應用程序。我正在嘗試使這個嵌入式腳本創建模態的對話框之一,但我沒有太大的成功。如何在tkinter中創建模態對話框?
任何人都可以指出做出模態對話的方式嗎?我是否需要使用windows函數或者只有Tk或Python函數足夠?
對於我GOOGLE了模樣的功能應該做的魔術以下組合,但他們似乎沒有工作,我期待的方式:
focus_set()
grab_set()
transient(parent)
grab_set
是製作一個窗口「的應用程序的適當機制模式」。也就是說,它從同一應用程序中的所有其他窗口獲取所有輸入(即:在同一進程中的其他Tkinter窗口),但它允許您與其他應用程序交互。
如果您希望對話框爲全局模態,請使用grab_set_global
。這將接管全部整個系統的鍵盤和鼠標輸入。使用此功能時必須非常小心,因爲如果您有一個可阻止應用程序釋放抓取的錯誤,則可以輕鬆地將自己鎖定在計算機外面。
當我需要這樣做時,在開發過程中,我會嘗試編寫一個防彈故障安全系統,例如定時器,它會在一段固定的時間後釋放抓鬥。
'grab_set_global'做到了 – Mac
在我的一個項目中,我使用了Tcl窗口管理器屬性'-disabled'到父窗口,該窗口稱爲(模態)頂層對話窗口。
不知道你和你的MFC應用程序顯示其窗口創建或Tcl的玩藝,但如果你的父窗口Tk的基礎,你可以這樣做:
在Python裏面簡單地調用到父窗口你的頂層窗口的創建方法:
MyParentWindow.wm_attributes("-disabled", True)
後,你得到了你想要的東西與你的模式窗口,不要忘記用一個回調函數的模態窗口內,再次啓用父窗口上輸入! (否則你將無法再與你的父窗口進行互動!):
MyParentWindow.wm_attributes("-disabled", False)
一個Tkinter的(TCL 8.6版)Python的例子(在Windows 10 64位測試):
# Python 3+
import tkinter as tk
from tkinter import ttk
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.minsize(300, 100)
self.button = ttk.Button(self, text="Call toplevel!", command=self.Create_Toplevel)
self.button.pack(side="top")
def Create_Toplevel(self):
# THE CLUE
self.wm_attributes("-disabled", True)
# Creating the toplevel dialog
self.toplevel_dialog = tk.Toplevel(self)
self.toplevel_dialog.minsize(300, 100)
# Tell the window manager, this is the child widget.
# Interesting, if you want to let the child window
# flash if user clicks onto parent
self.toplevel_dialog.transient(self)
# This is watching the window manager close button
# and uses the same callback function as the other buttons
# (you can use which ever you want, BUT REMEMBER TO ENABLE
# THE PARENT WINDOW AGAIN)
self.toplevel_dialog.protocol("WM_DELETE_WINDOW", self.Close_Toplevel)
self.toplevel_dialog_label = ttk.Label(self.toplevel_dialog, text='Do you want to enable my parent window again?')
self.toplevel_dialog_label.pack(side='top')
self.toplevel_dialog_yes_button = ttk.Button(self.toplevel_dialog, text='Yes', command=self.Close_Toplevel)
self.toplevel_dialog_yes_button.pack(side='left', fill='x', expand=True)
self.toplevel_dialog_no_button = ttk.Button(self.toplevel_dialog, text='No')
self.toplevel_dialog_no_button.pack(side='right', fill='x', expand=True)
def Close_Toplevel(self):
# IMPORTANT!
self.wm_attributes("-disabled", False) # IMPORTANT!
self.toplevel_dialog.destroy()
# Possibly not needed, used to focus parent window again
self.deiconify()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
對於有關Tcl窗口管理器屬性的更多信息,請查看Tcl文檔:https://wiki.tcl.tk/9457
'w.grab_set()'(或更無禮的'w.grab_set_global()')應該這樣做。搜索「模態」[這裏](http://www.pythonware.com/library/tkinter/introduction/dialog-windows.htm)。 – martineau
@martineau jsut嘗試過,但它不起作用。我仍然可以訪問底層的MFC應用程序。任何其他想法? – Mac