我正在尝试在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函数时,它会创建新对象但不显示它。它保持在同一个屏幕上,我仍然可以像往常一样与它进行交互,就好像它根本没有改变scrreens!
我已经通过将print(id(self.frames['SearchResults']))
放入show_frame函数来检查新对象的创建,并且每次按下按钮时都会显示不同的ID。
我也知道问题不在self.controller.show_frame('SearchResults')
行,因为我已经尝试了self.controller.show_frame('MainMenu')
,这样可以正常工作。
我做错了什么?
答案 0 :(得分:3)
考虑以下代码:
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
页面内的小部件。