Python GUI編程之tkinter模塊Toplevel控件實(shí)現(xiàn)搭建父子窗口
Toplevel控件搭建父子窗口
最近,用Python給單位里用的“智慧食堂”系統(tǒng)編制了一個(gè)餐卡充值文件生成器,自動(dòng)匹配餐卡號(hào)并快速生成導(dǎo)入數(shù)據(jù)用的Excel表格,截圖如下:
使用tkinter Toplevel控件彈出子窗口,用作設(shè)置備注的子窗口。在編程過(guò)程中,邊學(xué)邊寫(xiě)探索到不少新知識(shí),簡(jiǎn)單介紹如下:
最簡(jiǎn)明的父子窗口框架
創(chuàng)建一個(gè)主窗口、一個(gè)子窗口,各放一個(gè)按鈕,代碼如下:
import win32api, tkinter as tk def _toplevel(): top = tk.Toplevel(root) top.title("Toplevel Window") W,H=400,300 top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') btn_Close = tk.Button(top, text="Close", command=top.destroy) btn_Close.pack() if __name__=='__main__': # 創(chuàng)建主窗口 root = tk.Tk() root.title("Main Window") # 獲取windows系統(tǒng)桌面分辨率 X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1) W,H=600,480 root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') # 創(chuàng)建一個(gè)打開(kāi)Toplevel窗口的按鈕 btn_Open = tk.Button(root, text="Open Toplevel", command=_toplevel) btn_Open.pack() # 運(yùn)行Tkinter事件循環(huán) root.mainloop()
上述代碼的缺點(diǎn)是主窗口上的Open按鈕可以反復(fù)點(diǎn)擊打開(kāi)多個(gè)子窗口,要想辦法按需要來(lái)屏蔽它的點(diǎn)擊功能。
改進(jìn)屏蔽和開(kāi)放按鈕
以下代碼可以調(diào)整按鈕的使用狀態(tài):tk.DISABLED、tk.NORMAL
button.config(state=tk.DISABLED)
button.config(state=tk.NORMAL)
打開(kāi)子窗口時(shí),Open按鈕的狀態(tài)改為tk.DISABLED,此時(shí)已無(wú)法點(diǎn)擊了。
import win32api, tkinter as tk class TopWindow: def __init__(self, parent): top = self.top = tk.Toplevel(parent) top.title("Toplevel Window") W,H=400,300 top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') btn_Close = tk.Button(top, text="Close", command=self.on_close) btn_Close.pack() def on_close(self): btn_Open.config(state=tk.NORMAL) self.top.destroy() def on_open(): TopWindow(root) btn_Open.config(state=tk.DISABLED) if __name__=='__main__': root = tk.Tk() root.title("Main Window") X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1) W,H=600,480 root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') btn_Open = tk.Button(root, text="Open Toplevel", command=on_open) btn_Open.pack() root.mainloop()
改進(jìn)子窗口始終在主窗口之上
top.transient(root) # 設(shè)置Toplevel窗口始終在主窗口root的上方
import win32api, tkinter as tk class TopWindow: def __init__(self, parent): top = self.top = tk.Toplevel(parent) top.title("Toplevel Window") W,H=400,300 top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') top.transient(root) # 設(shè)置Toplevel窗口始終在主窗口上方 btn_Close = tk.Button(top, text="Close", command=self.on_close) btn_Close.pack() def on_close(self): btn_Open.config(state=tk.NORMAL) self.top.destroy() def on_open(): TopWindow(root) btn_Open.config(state=tk.DISABLED) if __name__=='__main__': root = tk.Tk() root.title("Main Window") X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1) W,H=600,480 root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') btn_Open = tk.Button(root, text="Open Toplevel", command=on_open) btn_Open.pack() root.mainloop()
另外一種方法也能設(shè)置子窗口永遠(yuǎn)在前:
top.wm_attributes('-topmost', True) # 設(shè)置Toplevel窗口在所有窗口的上方
兩種方法的區(qū)別在于后者是全局的設(shè)置,它使得子窗口在操作系統(tǒng)中所有窗口的上面,包括其它應(yīng)用程序的窗口。
如下圖,請(qǐng)比較一下與上一張截圖的效果有啥區(qū)別:
改進(jìn)增加子窗口的關(guān)閉協(xié)議
如下圖,直接點(diǎn)擊子窗口右上關(guān)閉按鈕,只觸發(fā)窗口默認(rèn)的top.destroy事件。這樣關(guān)閉子窗口后,主窗口的按鈕狀態(tài)并不能恢復(fù);以下代碼使得子窗口的"WM_DELETE_WINDOW"關(guān)閉協(xié)議綁定了自定義的關(guān)閉事件self.onclose:
top.protocol("WM_DELETE_WINDOW", self.on_close)
完整代碼如下:
import win32api, tkinter as tk class TopWindow: def __init__(self, parent): top = self.top = tk.Toplevel(parent) top.title("Toplevel Window") W,H=400,300 top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') top.transient(root) top.protocol("WM_DELETE_WINDOW", self.on_close) btn_Close = tk.Button(top, text="Close", command=self.on_close) btn_Close.pack() def on_close(self): btn_Open.config(state=tk.NORMAL) self.top.destroy() def on_open(): TopWindow(root) btn_Open.config(state=tk.DISABLED) if __name__=='__main__': root = tk.Tk() root.title("Main Window") X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1) W,H=600,480 root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') btn_Open = tk.Button(root, text="Open Toplevel", command=on_open) btn_Open.pack() root.mainloop()
改進(jìn)使子窗口長(zhǎng)獲焦點(diǎn)
top.grab_set() # 確保Toplevel窗口長(zhǎng)獲焦點(diǎn)
使用這個(gè)方法,前面提到的按鈕狀態(tài)的切換以及子窗口綁定關(guān)閉協(xié)議的代碼都不需要了,非常簡(jiǎn)潔。top.grab_set()
配合top.transient(root)
共同使用(如下標(biāo)注紅色部分),效果最佳:
import win32api, tkinter as tk class TopWindow: def __init__(self, parent): top = self.top = tk.Toplevel(parent) top.title("Toplevel Window") W,H=400,300 top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') top.grab_set() top.transient(root) btn_Close = tk.Button(top, text="Close", command=top.destroy) btn_Close.pack() def on_open(): TopWindow(root) if __name__=='__main__': root = tk.Tk() root.title("Main Window") X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1) W,H=600,480 root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') btn_Open = tk.Button(root, text="Open Toplevel", command=on_open) btn_Open.pack() root.mainloop()
源代碼復(fù)制框如下:
import win32api, tkinter as tk class TopWindow: def __init__(self, parent): top = self.top = tk.Toplevel(parent) top.title("Toplevel Window") W,H=400,300 top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') top.grab_set() top.transient(root) btn_Close = tk.Button(top, text="Close", command=top.destroy) btn_Close.pack() def on_open(): TopWindow(root) if __name__=='__main__': root = tk.Tk() root.title("Main Window") X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1) W,H=600,480 root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}') btn_Open = tk.Button(root, text="Open Toplevel", command=on_open) btn_Open.pack() root.mainloop()
總結(jié)
通過(guò)對(duì)toplevel控件的編程操練,掌握了tkinter子窗口的調(diào)用方法,了解了topleve的多種特殊方法、響應(yīng)事件以及綁定協(xié)議。
到此這篇關(guān)于Python GUI編程之tkinter模塊Toplevel控件實(shí)現(xiàn)搭建父子窗口的文章就介紹到這了,更多相關(guān)Python Toplevel搭建父子窗口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python手動(dòng)實(shí)現(xiàn)Hough圓變換的示例代碼
Hough圓變換的原理相信大家都非常清楚了,但是手動(dòng)實(shí)現(xiàn)的比較少。這篇文章將為大家介紹手動(dòng)實(shí)現(xiàn)Hough圓變換的示例代碼,需要的可以了解一下2022-01-01Python實(shí)現(xiàn)iOS自動(dòng)化打包詳解步驟
這篇文章主要介紹了Python實(shí)現(xiàn)iOS自動(dòng)化打包詳解步驟,文中通過(guò)示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-10-10Python json轉(zhuǎn)字典字符方法實(shí)例解析
這篇文章主要介紹了Python json轉(zhuǎn)字典字符代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04關(guān)于python中plt.hist參數(shù)的使用詳解
今天小編就為大家分享一篇關(guān)于python中plt.hist參數(shù)的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-1110款最好的Web開(kāi)發(fā)的 Python 框架
這篇文章主要介紹了10款最好的Web開(kāi)發(fā)的 Python 框架,總結(jié)的都是非常常用的而且評(píng)價(jià)都非常不錯(cuò)的框架,需要的朋友可以參考下2015-03-03Django中redis的使用方法(包括安裝、配置、啟動(dòng))
下面小編就為大家分享一篇Django中redis的使用方法(包括安裝、配置、啟動(dòng)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02Python利用numpy實(shí)現(xiàn)三層神經(jīng)網(wǎng)絡(luò)的示例代碼
這篇文章主要介紹了Python利用numpy實(shí)現(xiàn)三層神經(jīng)網(wǎng)絡(luò)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Python Dict 到 Dataclass實(shí)現(xiàn)高效數(shù)據(jù)訪問(wèn)與管理的兩種方式(推薦)
本文介紹了Python中的字典和DataClass兩種數(shù)據(jù)結(jié)構(gòu),并探討了如何將字典轉(zhuǎn)換為DataClass,字典適用于鍵值對(duì)存儲(chǔ),感興趣的朋友一起看看吧2024-12-12