[英]Python3.x: tkinter (ttk) stop displaying widget
所以我一直試圖用tkinter制作一些基本的GUI(不要與Tkinter混淆),我遇到了一個問題,我知道沒有解決辦法,也無法在全能的Google上找到任何東西...我有一個我的電腦上有一個目錄表的小型SQLite數據庫。 我想將所有目錄路徑繪制到標簽中,並在該標簽旁邊添加一個“rempve”按鈕。 該按鈕應該能夠從數據庫中刪除目錄,並將其從GUI中刪除。 我還有一個“添加”按鈕,可以在其中添加目錄到數據庫,這個新目錄應該顯示在GUI中。 這是我的基本布局:
---------------
| ADD |
|dir1 REMOVE|
|dir2 REMOVE|
---------------
我使用gridlayout來顯示按鈕和標簽。 大多數工作都有效,所有與數據庫相關的東 此外,當啟動GUI時,當前目錄和“刪除”按鈕很好地顯示。 但是......當使用“刪除”按鈕時,即使目錄不在數據庫中,目錄也不會從GUI中消失,重新啟動GUI當然會修復它。 添加標簽有效...但我不確定我是否正確地做到了......
我怎么能以某種方式用新信息“重新繪制”GUI? 這是我的GUI代碼:
class GUI():
def __init__(self,db):
self.root = Tk()
self.root.title("Example")
self.frame = ttk.Frame(self.root, padding="3 3 12 12")
self.frame.rowconfigure(5, weight=1)
self.frame.columnconfigure(5, weight=1)
self.frame.grid(sticky=W+E+N+S)
lbl = ttk.Label(self.frame, text="", width=17)
lbl.grid(row=0, column=2, sticky=W)
ttk.Button(self.frame, text="Add directory", command=lambda:self.load_file(db), width=30).grid(row=0, column=0, sticky=W, padx=(500,50))
ttk.Button(self.frame, text="Sort files", command=lambda:self.sort(db,lbl), width=17).grid(row=0, column=1, sticky=W)
self.draw(db)
self.root.mainloop()
def load_file(self,db):
fname = filedialog.askdirectory()
db.addPath(fname)
self.draw(db)
def remove_dir(self,db,pid):
db.removePath(pid)
self.draw(db)
def sort(self,db,lbl):
lbl['text'] = 'Sorting...'
sortFiles.moveFiles(db)
lbl['text'] = 'Done!'
def draw(self,db):
i = 0
paths = db.getPaths()
for path in paths:
ttk.Label(self.frame,text=path[1]).grid(row=1+i,column=0,sticky=W)
ttk.Button(self.frame, text="Remove directory", command=lambda:self.remove_dir(db,path[0]), width=17).grid(row=1+i,column=1, sticky=E)
i = i+1
for child in self.frame.winfo_children(): child.grid_configure(padx=5, pady=5)
if i == 0:
ttk.Label(self.root,text='No directories added yet').grid(row=1,column=0,sticky=W)
如果您希望每次添加或刪除某些內容時重繪GUI,則需要先創建舊的小部件,然后再創建新的小部件。 例如:
def draw(self, db):
# first, delete any existing widgets
for child in self.frame.winfo_children():
child.destroy()
# next, redraw all the widgets
paths = db.getPaths()
for path in paths:
...
你有另一個錯誤,就是你如何使用lambda。 由於它與問題中的代碼一致,所有回調都將看到相同的值。 通過將值指定為lambda的關鍵字參數,您將獲得正確的值:
ttk.Button(..., command=lambda p=path[0]:self.remove_dir(db, p)...)
與實際問題無關,我認為你不需要傳遞db
。 假設您只使用一個db,我建議您在GUI
構造函數中執行self.db = db
。 這將使您的代碼更容易維護,因為您的方法簽名將被簡化。
最后,當您刪除一個項目時,確實沒有必要完全重繪GUI。 您一次只能刪除一個標簽和按鈕。 這需要您花一點時間考慮如何管理程序中的數據。 例如,如果您保留對每個標簽和按鈕的引用,則可以在從數據庫中刪除路徑時將其刪除。 您的removeDir
函數可能類似於:
def removeDir(self, pid):
label, button = self.widgets(pid)
label.destroy()
button.destroy()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.