tkinter frame does not show on startup
- by Jzz
this is my first question on SO, so correct me please if I make a fool of myself.
I have this fairly complicated python / Tkinter application (python 2.7). On startup, the __init__ loads several frames, and loads a database. When that is finished, I want to set the application to a default state (there are 2 program states, 'calculate' and 'config'). Setting the state of the application means that the appropriate frame is displayed (using grid). When the program is running, the user can select a program state in the menu.
Problem is, the frame is not displayed on startup. I get an empty application (menu bar and status bar are displayed). When I select a program state in the menu, the frame displays as it should.
Question:
What am I doing wrong? Should I update idletasks? I tried, but no result. Anything else?
Background:
I use the following to switch program states:
def set_program_state(self, state):
'''sets the program state'''
#try cleaning all the frames:
try:
self.config_frame.grid_forget()
except:
pass
try:
self.tidal_calculations_frame.grid_forget()
except:
pass
try:
self.tidal_grapth_frame.grid_forget()
except:
pass
if state == "calculate":
print "Switching to calculation mode"
self.tidal_calculations_frame.grid() #frame is preloaded
self.tidal_calculations_frame.fill_data(routes=self.routing_data.routes,
deviations=self.misc_data.deviations,
ship_types=self.misc_data.ship_types)
self.tidal_grapth_frame.grid()
self.program_state = "calculate"
elif state == "config":
print "Switching to config mode"
self.config_frame = GUI_helper.config_screen_frame(self, self.user) #load frame first (contents depend on type of user)
self.config_frame.grid()
self.program_state = "config"
I understand that this is kind of messy to read, so I simplified things for testing, using this:
def set_program_state(self, state):
'''sets the program state'''
#try cleaning all the frames:
try:
self.testlabel_1.grid_forget()
except:
pass
try:
self.testlabel_2.grid_forget()
except:
pass
if state == "calculate":
print "switching to test1"
self.testlabel_1 = tk.Label(self, text="calculate", borderwidth=1, relief=tk.RAISED)
self.testlabel_1.grid(row=0, sticky=tk.W+tk.E)
elif state == "config":
print "switching to test1"
self.testlabel_2 = tk.Label(self, text="config", borderwidth=1, relief=tk.RAISED)
self.testlabel_2.grid(row=0, sticky=tk.W+tk.E)
But the result is the same. The frame (or label in this test) is not displayed at startup, but when the user selects the state (calling the same function) the frame is displayed.
UPDATE
the sample code in the comments (thanks for that!) pointed me in another direction. Further testing revealed (what I think) the cause of the problem. Disabling the display of the status bar made the program work as expected. Turns out, I used pack to display the statusbar and grid to display the frames. And they are in the same container, so problems arise. I fixed that by using only pack inside the main container. But the same problem is still there.
This is what I use for the statusbar:
self.status = GUI_helper.StatusBar(self.parent)
self.status.pack(side=tk.BOTTOM, fill=tk.X)
And if I comment out the last line (pack), the config frame loads on startup, as per this line:
self.set_program_state("config")
But if I let the status bar pack inside the main window, the config frame does not show. Where it does show when the user asks for it (with the same command as above).