部落格園的密碼終于找回了
前言
偶爾使用python要繪制個簡單輸入提示框或者複選框窗體,使用tkinter的話繪制窗體也是很麻煩的,想着能不能把它自定義一個簡單可複用的提示框。然後便動手寫了一下,效果還可以
import tkinter as tk
from tkinter import ttk,messagebox
class Dialog():
def __init__(self):
self.master=tk.Toplevel()
self.master.withdraw()
self.style=ttk.Style()
self.master["background"]="#ffffff"
self.style.configure("G.TLabel",font=('微軟雅黑',11),foreground='#00bbcc',background="#ffffff")
self.style.configure('G.TFrame',background='#ffffff')
self.style.configure("G.TCheckbutton",background="#ffffff")
self.style.configure("G.TButton",background="#2b6e99",borderwidth=4)
self.top=ttk.Frame(self.master,style="G.TFrame")
self.middle=ttk.Frame(self.master,style="G.TFrame")
self.bottom=ttk.Frame(self.master)
self.top.pack(padx=10,fill="x")
self.middle.pack(padx=10,pady=5,fill="x")
self.bottom.pack(fill="both")
self.result=None
def show(self):
self.master.update()
self.width,self.height=self.master.winfo_reqwidth(),self.master.winfo_reqheight()
self.x,self.y=(self.master.winfo_screenwidth()-self.width)/2,(self.master.winfo_screenheight()-self.height)/2
self.master.resizable(False,False)
self.master.wm_attributes("-topmost",1)
self.master.geometry('%dx%d+%d+%d' % (self.width, self.height, self.x, self.y))
self.master.deiconify()
self.master.grab_set()
self.master.wait_window()
return self.result
def builder(self):
return self
def exit(self):
self.master.destroy()
def addConfirmCancelBtn(self):
self.confirmBtn=ttk.Button(self.bottom,text="送出",style="G.TButton",command=self.confirm)
self.confirmBtn.grid(row=0,column=0,padx=10,pady=10)
self.cancelBtn=ttk.Button(self.bottom,text="取消",style="G.TButton",command=self.cancel)
self.cancelBtn.grid(row=0,column=1,padx=10,pady=10)
def addYesNoBtn(self):
self.confirmBtn=ttk.Button(self.bottom,text="是",style="G.TButton",command=self.yes)
self.confirmBtn.grid(row=0,column=0,padx=10,pady=10)
self.cancelBtn=ttk.Button(self.bottom,text="否",style="G.TButton",command=self.no)
self.cancelBtn.grid(row=0,column=1,padx=10,pady=10)
def addOkBtn(self):
tk.Label(self.bottom,width=10).grid(row=0,column=0,padx=5,pady=5)
self.cancelBtn=ttk.Button(self.bottom,text="确定",style="G.TButton",command=self.ok)
self.cancelBtn.grid(row=0,column=1,padx=5,pady=5)
def confirm(self):
pass
def cancel(self):
pass
def ok(self):
pass
def yes(self):
pass
def no(self):
pass
class InputDialog(Dialog):
def __init__(self,title,dic):
super().__init__()
self.master.title(title)
self.title=ttk.Label(self.top,text=title,style="G.TLabel")
self.title.pack(fill="x")
self.dic=dic
def builder(self):
keys=list(self.dic.keys())
for i in range(0,len(keys)):
key=keys[i]
val=self.dic[key]
self.dic[key+"-k"]=tk.Label(self.middle,text=key,font=('微軟雅黑',10),bg="#ffffff")
self.dic[key+"-k"].grid(row=i,column=0,sticky="w")
self.dic[key+"-v"]=tk.StringVar()
self.dic[key+'-v'].set(val['text'])
if val['type']=='password':
ttk.Entry(self.middle,width=20,textvariable=self.dic[key+'-v'],show='*').grid(row=i,column=1,columnspan=2)
else:
ttk.Entry(self.middle,width=20,textvariable=self.dic[key+'-v']).grid(row=i,column=1,columnspan=2)
self.addConfirmCancelBtn()
return self
def confirm(self):
keys=list(self.dic.keys())
for key in keys:
if "-k" in key:
del self.dic[key]
if '-v' in key:
val=self.dic[key].get()
self.dic[str(key).strip("-v")]['text']=val
del self.dic[key]
self.result=self.dic
self.exit()
def cancel(self):
self.result=None
self.exit()
class AlertDialog(Dialog):
def __init__(self,title,text):
super().__init__()
self.title=title
self.text=text
def show(self):
return messagebox.showinfo(self.title,self.text)
class CheckButtonDialog(Dialog):
def __init__(self,title,dic):
super().__init__()
self.master.title(title)
self.title = ttk.Label(self.top, text=title,style="G.TLabel")
self.title.pack(fill="x")
self.dic=dic
def builder(self):
self.keys=list(self.dic.keys())
for key in self.keys:
self.dic[key+"-c"]=tk.IntVar()
self.dic[key+"-c"].set(self.dic[key]["state"])
ttk.Checkbutton(self.middle,text=key,variable=self.dic[key+"-c"],style="G.TCheckbutton").pack(pady=2,anchor="w",padx=10)
self.addOkBtn()
return self
def ok(self):
for key in self.keys:
state=self.dic[key+"-c"].get()
self.dic[key]["state"]=state
del self.dic[key+"-c"]
self.result=self.dic
self.exit()
if __name__ =="__main__":
root = tk.Tk()
tk.Button(root, text='對話框', command=lambda:print(AlertDialog("對話框舉例","hello world").builder().show())).pack(pady=5)
tk.Button(root,text="輸入框",command=lambda:print(InputDialog("輸入框舉例",{"使用者名":{"text":"零度熱冰","type":"text"},"密碼":{"text":"123456","type":"password"}}).builder().show())).pack(pady=5)
tk.Button(root,text="多選框",command=lambda :print(CheckButtonDialog("多選框舉例",{"CSDNCSDNCSDN":{"state":1},"部落格園":{"state":0},"CSDN1":{"state":1},"部落格園2":{"state":0}}).builder().show())).pack(pady=5)
root.mainloop()
看看輸入框效果

基本和tkinter提示框的風格差不多,但是唯一不好的是ttk button 的boderwidth屬性好像不起作用
show()之後會傳回最終的結果
多選框效果