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é)邊寫探索到不少新知識(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è)打開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)擊打開多個(gè)子窗口,要想辦法按需要來(lái)屏蔽它的點(diǎn)擊功能。
改進(jìn)屏蔽和開放按鈕
以下代碼可以調(diào)整按鈕的使用狀態(tài):tk.DISABLED、tk.NORMAL
button.config(state=tk.DISABLED)
button.config(state=tk.NORMAL)

打開子窗口時(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中Conda常用命令的超詳細(xì)學(xué)習(xí)筆記
Anaconda是一個(gè)包含數(shù)據(jù)科學(xué)常用包的Python發(fā)行版本,可以用來(lái)安裝和管理不同版本的Python程序包,本文總結(jié)了Anaconda一些常用命令,希望對(duì)大家有所幫助2026-06-06
詳細(xì)講解用Python發(fā)送SMTP郵件的教程
這篇文章主要詳細(xì)講解了用Python發(fā)送SMTP郵件的教程,包括在郵件中添加圖片等文件,強(qiáng)烈推薦!需要的朋友可以參考下2015-04-04
Pandas Shift函數(shù)的基礎(chǔ)入門學(xué)習(xí)筆記
shift函數(shù)是對(duì)數(shù)據(jù)進(jìn)行移動(dòng)的操作,下面這篇文章主要給大家介紹了關(guān)于Pandas Shift函數(shù)的基礎(chǔ)入門學(xué)習(xí)筆記,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11
vscode pycharm配置miniconda環(huán)境全過(guò)程
本文介紹了在Mac上通過(guò)Homebrew安裝Miniconda并配置VSCode和PyCharm環(huán)境的方法,包括刪除環(huán)境、配置Python插件和選擇解釋器等步驟2025-10-10
Python?網(wǎng)頁(yè)請(qǐng)求之requests庫(kù)的使用詳解
requests?是?Python?中比較常用的網(wǎng)頁(yè)請(qǐng)求庫(kù),主要用來(lái)發(fā)送?HTTP?請(qǐng)求,在使用爬蟲或測(cè)試服務(wù)器響應(yīng)數(shù)據(jù)時(shí)經(jīng)常會(huì)用到,使用起來(lái)十分簡(jiǎn)潔,這篇文章主要介紹了Python?網(wǎng)頁(yè)請(qǐng)求之requests庫(kù)的使用詳解,需要的朋友可以參考下2022-09-09
對(duì)pyqt5中QTabWidget的相關(guān)操作詳解
今天小編就為大家分享一篇對(duì)pyqt5中QTabWidget的相關(guān)操作詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06
Python3.7基于hashlib和Crypto實(shí)現(xiàn)加簽驗(yàn)簽功能(實(shí)例代碼)
這篇文章主要介紹了Python3.7基于hashlib和Crypto實(shí)現(xiàn)加簽驗(yàn)簽功能,環(huán)境是基于python3.7,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
Python OpenCV對(duì)圖像進(jìn)行模糊處理詳解流程
OpenCV是一個(gè)基于BSD許可(開源)發(fā)行的跨平臺(tái)計(jì)算機(jī)視覺庫(kù),可以運(yùn)行在Linux、Windows、Android和Mac OS操作系統(tǒng)上。它輕量級(jí)而且高效——由一系列 C 函數(shù)和少量 C++ 類構(gòu)成,同時(shí)提供了Python、Ruby、MATLAB等語(yǔ)言的接口,實(shí)現(xiàn)了圖像處理和計(jì)算機(jī)視覺方面很多通用算法2021-10-10
python實(shí)現(xiàn)圖片數(shù)據(jù)增強(qiáng)的示例詳解
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)圖片數(shù)據(jù)增強(qiáng)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以跟隨小編一起了解一下2023-10-10

