0

Python-tkinter beginner here...

I would like to fill the main window (MainWin) with 2 vertical labelFrames (ModeWin and StatusWin) using the object oriented approach found here: Best way to structure a tkinter application?

The code runs but no labelFrames at all :-(

import tkinter as tk
#-------------------------------------------------------------------------------
# CLASS
class ModeWin(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self,parent,bg='light blue')
        self.parent = parent
        self.lblFrame = tk.LabelFrame(self.parent, text="Mode", padx=20, pady=20)
        self.lblFrame.grid(row=0, column=0, sticky="ew")
        
        self.label = tk.Label(self.lblFrame, text="Text in ModeWin")
        self.lblFrame.grid()

class StatusWin(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self,parent,bg='light green')
        self.parent = parent
        self.lblFrame = tk.LabelFrame(self.parent, text="Status", padx=20, pady=20)
        self.lblFrame.grid(row=1, column=0, sticky="ew")

        self.label = tk.Label(self.lblFrame, text="Text in StatusWin")
        self.lblFrame.grid()
    
class MainWin(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)

        self.modeWin = ModeWin(self)
        self.statusWin = StatusWin(self)
        
    def start(self):
        self.mainloop()
        
#-------------------------------------------------------------------------------
# MAIN
def main():
    app = MainWin()
    app.start()

if __name__ == '__main__':
    main()

Would appreciate your advices on it. Thank you in advance

Steph
  • 7
  • 2

1 Answers1

0

As a general rule of thumb when inheriting from a frame, all child widgets should be a child of the class itself, not its parent. Otherwise, there's zero advantage of inheriting from the frame class. In other words, make the parent of the label frames self rather than self.parent.

You then need to call pack, place, or grid on your classes so that they appear.

Also, you need to either give the label frames a size or put one or more widgets in it. Otherwise, the frames will be 1x1 pixel and virtually impossible to see.

Finally, if you're only putting a single widget in a frame, such as putting the label frames in self, it's easiest to use pack rather than grid since you can get it to fill the frame with a single command and without having to remember to give the rows and columns weight.

Here's your code with all of those changes:

import tkinter as tk
#-------------------------------------------------------------------------------
# CLASS
class ModeWin(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self,parent,bg='light blue')
        self.parent = parent
        self.lblFrame = tk.LabelFrame(self, text="Mode", padx=20, pady=20)
        self.lblFrame.pack(fill="both", expand=True)

        self.label = tk.Label(self.lblFrame, text="Text in ModeWin")
        self.label.pack(side="top")

class StatusWin(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self,parent,bg='light green')
        self.parent = parent
        self.lblFrame = tk.LabelFrame(self, text="Status", padx=20, pady=20)
        self.lblFrame.pack(fill="both", expand=True)

        self.label = tk.Label(self.lblFrame, text="Text in StatusWin")
        self.label.pack(side="top")

class MainWin(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)

        self.modeWin = ModeWin(self)
        self.statusWin = StatusWin(self)

        self.modeWin.grid(row=0, column=0, sticky="ew")
        self.statusWin.grid(row=1, column=0, sticky="ew")

    def start(self):
        self.mainloop()

#-------------------------------------------------------------------------------
# MAIN
def main():
    app = MainWin()
    app.start()

if __name__ == '__main__':
    main()

screenshot

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • THANK YOU Bryan Oakley for your valuable answer. Your explanations are exactly what I needed. – Steph May 19 '22 at 07:31