[英]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.