這篇文章主要介紹了Python tkinter模塊彈出窗口及傳值回到主窗口操作,結合實例形式分析了Python使用tkinter模塊實現的彈出窗口及參數傳遞相關操作技巧,需要的朋友可以參考下
本文實例講述了Python tkinter模塊彈出窗口及傳值回到主窗口操作。分享給大家供大家參考,具體如下:
有些時候,我們需要使用彈出窗口,對程序的運行參數進行設置。有兩種選擇
一、標准窗口
如果只對一個參數進行設置(或者說從彈出窗口取回一個值),那么可以使用simpledialog
,導入方法:
from tkinter.simpledialog import askstring, askinteger, askfloat
完整例子
import tkinter as tk from tkinter.simpledialog import askstring, askinteger, askfloat # 接收一個整數 def print_integer(): res = askinteger("Spam", "Egg count", initialvalue=12*12) print(res) # 接收一個浮點數 def print_float(): res = askfloat("Spam", "Egg weight\n(in tons)", minvalue=1, maxvalue=100) print(res) # 接收一個字符串 def print_string(): res = askstring("Spam", "Egg label") print(res) root = tk.Tk() tk.Button(root, text='取一個字符串', command=print_string).pack() tk.Button(root, text='取一個整數', command=print_integer).pack() tk.Button(root, text='取一個浮點數', command=print_float).pack() root.mainloop()
二、自定義窗口
如果要設置的參數個數超過兩個,那么tkinter提供的標准窗口就處理不了了。
這就需要自定義一個窗口,那么問題來了:怎樣將自定義窗口中的數據傳回主窗口?
百度查詢,不外乎兩種方法:全局變量(global)、對象變量([]、{}等),都不是我想要的。
然后,去 stackoverflow 逛了一下,綜合了個問題的答案,得到兩個本人比較滿意的方案。
一種是松耦合,另一種是緊耦合
1)松耦合
說明:
主窗類,繼承了 tk.Tk
彈窗類,繼承了 tk.Toplevel
要點:
彈窗,將多個數據,打包,放入一個名為 username
的私有 list 對象,銷毀彈窗
主窗,待彈窗運行后,通過wait_window
方法,取得彈窗的名為 username
私有變量
完整代碼:
import tkinter as tk '''松耦合''' # 彈窗 class MyDialog(tk.Toplevel): def __init__(self): super().__init__() self.title('設置用戶信息') # 彈窗界面 self.setup_UI() def setup_UI(self): # 第一行(兩列) row1 = tk.Frame(self) row1.pack(fill="x") tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT) self.name = tk.StringVar() tk.Entry(row1, textvariable=self.name, width=20).pack(side=tk.LEFT) # 第二行 row2 = tk.Frame(self) row2.pack(fill="x", ipadx=1, ipady=1) tk.Label(row2, text='年齡:', width=8).pack(side=tk.LEFT) self.age = tk.IntVar() tk.Entry(row2, textvariable=self.age, width=20).pack(side=tk.LEFT) # 第三行 row3 = tk.Frame(self) row3.pack(fill="x") tk.Button(row3, text="取消", command=self.cancel).pack(side=tk.RIGHT) tk.Button(row3, text="確定", command=self.ok).pack(side=tk.RIGHT) def ok(self): self.userinfo = [self.name.get(), self.age.get()] # 設置數據 self.destroy() # 銷毀窗口 def cancel(self): self.userinfo = None # 空! self.destroy() # 主窗 class MyApp(tk.Tk): def __init__(self): super().__init__() #self.pack() # 若繼承 tk.Frame ,此句必須有! self.title('用戶信息') # 程序參數/數據 self.name = '張三' self.age = 30 # 程序界面 self.setupUI() def setupUI(self): # 第一行(兩列) row1 = tk.Frame(self) row1.pack(fill="x") tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT) self.l1 = tk.Label(row1, text=self.name, width=20) self.l1.pack(side=tk.LEFT) # 第二行 row2 = tk.Frame(self) row2.pack(fill="x") tk.Label(row2, text='年齡:', width=8).pack(side=tk.LEFT) self.l2 = tk.Label(row2, text=self.age, width=20) self.l2.pack(side=tk.LEFT) # 第三行 row3 = tk.Frame(self) row3.pack(fill="x") tk.Button(row3, text="設置", command=self.setup_config).pack(side=tk.RIGHT) # 設置參數 def setup_config(self): # 接收彈窗的數據 res = self.ask_userinfo() #print(res) if res is None: return # 更改參數 self.name, self.age = res # 更新界面 self.l1.config(text=self.name) self.l2.config(text=self.age) # 彈窗 def ask_userinfo(self): inputDialog = MyDialog() self.wait_window(inputDialog) # 這一句很重要!!! return inputDialog.userinfo if __name__ == '__main__': app = MyApp() app.mainloop()
2)緊耦合
說明:
主窗類,繼承了 tk.Tk
彈窗類,繼承了 tk.Toplevel
要點:
彈窗,顯式地保存父窗口,顯式地修改父窗口數據,顯式地更新父窗口部件,最后銷毀彈窗
主窗,待彈窗運行后,通過wait_window
方法,返回 None
完整代碼:
import tkinter as tk '''緊耦合''' # 彈窗 class PopupDialog(tk.Toplevel): def __init__(self, parent): super().__init__() self.title('設置用戶信息') self.parent = parent # 顯式地保留父窗口 # 第一行(兩列) row1 = tk.Frame(self) row1.pack(fill="x") tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT) self.name = tk.StringVar() tk.Entry(row1, textvariable=self.name, width=20).pack(side=tk.LEFT) # 第二行 row2 = tk.Frame(self) row2.pack(fill="x", ipadx=1, ipady=1) tk.Label(row2, text='年齡:', width=8).pack(side=tk.LEFT) self.age = tk.IntVar() tk.Entry(row2, textvariable=self.age, width=20).pack(side=tk.LEFT) # 第三行 row3 = tk.Frame(self) row3.pack(fill="x") tk.Button(row3, text="取消", command=self.cancel).pack(side=tk.RIGHT) tk.Button(row3, text="確定", command=self.ok).pack(side=tk.RIGHT) def ok(self): # 顯式地更改父窗口參數 self.parent.name = self.name.get() self.parent.age = self.age.get() # 顯式地更新父窗口界面 self.parent.l1.config(text=self.parent.name) self.parent.l2.config(text=self.parent.age) self.destroy() # 銷毀窗口 def cancel(self): self.destroy() # 主窗 class MyApp(tk.Tk): def __init__(self): super().__init__() # self.pack() # 若繼承 tk.Frame,此句必須有!!! self.title('用戶信息') # 程序參數 self.name = '張三' self.age = 30 # 程序界面 self.setupUI() def setupUI(self): # 第一行(兩列) row1 = tk.Frame(self) row1.pack(fill="x") tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT) self.l1 = tk.Label(row1, text=self.name, width=20) self.l1.pack(side=tk.LEFT) # 第二行 row2 = tk.Frame(self) row2.pack(fill="x") tk.Label(row2, text='年齡:', width=8).pack(side=tk.LEFT) self.l2 = tk.Label(row2, text=self.age, width=20) self.l2.pack(side=tk.LEFT) # 第三行 row3 = tk.Frame(self) row3.pack(fill="x") tk.Button(row3, text="設置", command=self.setup_config).pack(side=tk.RIGHT) # 設置參數 def setup_config(self): pw = PopupDialog(self) self.wait_window(pw) # 這一句很重要!!! return if __name__ == '__main__': app = MyApp() app.mainloop()
效果圖
《Python編碼操作技巧總結》、《Python數據結構與算法教程》、《Python函數使用技巧總結》、《Python字符串操作技巧匯總》及《Python入門與進階經典教程》