Reputation: 17
I'm currently trying to create a program in tkinter that has multiple screens, however I am running into a strange problem:when I try to raise a particular screen to the front, it doesnt appear. The code I use to create the differnt screens is this:
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()
Then the user can use the Search Screens to specify the criteria to search for, then the doSearch function is called which should destroy the old SearchResults screen (by popping from the self.frames dict and garbage collecting).
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]
However, the problem is that when I try running the doSearch function it creates the new object but doesn't display it. It remains on the same screen and I can still interact with it as usual, as if it didnt change scrreens at all!
I have checked the creation of new objects by putting print(id(self.frames['SearchResults']))
in the show_frame function and it shows a different ID each time I press the button).
I also know that the problem is not with the self.controller.show_frame('SearchResults')
line as I have tried self.controller.show_frame('MainMenu')
and this worked as expected.
What have I done wrong?
Upvotes: 0
Views: 43
Reputation: 385970
Consider this code:
def doSearch(self,* args,** kwargs):
...
frame=SearchResults...)
pageName = SearchResults.__name__
self.controller.frames[pageName]=frame
self.controller.show_frame('SearchResults')
You never add the frame the the controller by calling grid
. You likely need to add this statement:
frame.grid(row=0, column=0, sticky='nsew')
I can't see any reason for needing to take a frame off of the list (without destroying it!) and putting a new one in its place. You've created a memory leak. Intead, you should just add a method in SearchResults
that recreates or resets the widgets inside the existing SearchResults
page.
Upvotes: 3