[英]Python 3: Tkinter frames and unexpected behaviour
我目前正在嘗試在tkinter中創建一個具有多個屏幕的程序,但是我遇到了一個奇怪的問題:當我嘗試將特定屏幕提升到前面時,它沒有出現。 我用來創建不同屏幕的代碼是這樣的:
class PokemonDecklistCreatorApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side='top', fill='both', expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (MainMenu, DecksMenu, DeckEditor, CardViewerDeckEditor,DeckNotes,SearchMenu, StandardSearch, AdvancedSearch, RandomSearch, SearchResults,CardViewerSearchResults, ExtrasMenu, CardExplanationGuide, AboutProgram):
try:
frame = F(parent=container, controller=self)
pageName = F.__name__
self.frames[pageName] = frame
frame.grid(row=0, column=0, sticky='nsew')
except Exception as e:
print(e)
self.show_frame('MainMenu')
def show_frame(self, page):
frame = self.frames[page]
frame.tkraise()
然后,用戶可以使用“搜索屏幕”指定要搜索的條件,然后調用doSearch函數,該函數應該破壞舊的SearchResults屏幕(通過從self.frames dict和垃圾回收中彈出)。
class RandomSearch(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.parent = parent
[some widgety code here]
self.btnSearch = tk.Button(self, text='Gotta Search \'em All!', command=self.doSearch, font=('Lucida Grande',24))
self.btnSearch.place(x=450, y=670, width=500, height=40)
def doSearch(self,* args,** kwargs):
self.controller.frames.pop('SearchResults')
frame=SearchResults(parent=self.parent,controller=self.controller,searchTerms=[])
pageName = SearchResults.__name__
self.controller.frames[pageName]=frame
self.controller.show_frame('SearchResults')
class SearchResults(tk.Frame):
def __init__(self, parent, controller,searchTerms=None):
tk.Frame.__init__(self, parent)
self.controller = controller
[more widgety stuff]
但是,問題在於,當我嘗試運行doSearch函數時,它將創建新對象,但不顯示它。 它保留在同一屏幕上,我仍然可以像往常一樣與它進行交互,就好像它根本沒有改變屏幕一樣!
我已經通過將print(id(self.frames['SearchResults']))
放在show_frame函數中來檢查是否創建了新對象,每次按下按鈕時,它都會顯示一個不同的ID。
我也知道問題不在於self.controller.show_frame('SearchResults')
行,因為我嘗試了self.controller.show_frame('MainMenu')
並且按預期工作。
我做錯了什么?
考慮以下代碼:
def doSearch(self,* args,** kwargs):
...
frame=SearchResults...)
pageName = SearchResults.__name__
self.controller.frames[pageName]=frame
self.controller.show_frame('SearchResults')
永遠不要通過調用grid
將框架添加到控制器中。 您可能需要添加以下語句:
frame.grid(row=0, column=0, sticky='nsew')
我看不出有任何理由需要從列表中刪除一個框架(而不破壞它!)並放置一個新的框架。 您創建了內存泄漏。 Intead,您只需在SearchResults
中添加一個方法即可在現有SearchResults
頁面內重新創建或重置小部件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.