-1

As previously advocated (Best way to structure a tkinter application), I am trying to apply an object oriented approach to tkinter GUI structure.

I am trying to place widgets, like the Radiobutton below in Labelframes:

import tkinter as tk

root = tk.Tk()
root.title("GUI")
root.geometry('640x480+200+200')

lf0 = tk.LabelFrame(root, text='0 Label Frame', height=100, width=620)
lf0.grid(row=0, column=0, padx=10)

lf1 = tk.LabelFrame(root, text='1 Label Frame', height=100, width=620)
lf1.grid(row=1, column=0, padx=10)

lf2 = tk.LabelFrame(root, text='2 Label Frame')
lf2.grid(row=2, column=0, padx=10)

rb1 = tk.Radiobutton(lf2, text='set')
rb1.grid(padx=287, pady=29, sticky='ew')

root.mainloop()

The following results in a similar GUI layout, but I'm not able to place widgets within the label frames using this approach.

import tkinter as tk


class RadioBut(tk.Radiobutton):
    def __init__(self, parent, txt, r, c, *args, **kwargs):
    #  def __init__(self, parent, loc, txt, r, c, *args, **kwargs):
        tk.Radiobutton.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        # self.loc = loc
        rb = tk.Radiobutton(parent, text=txt)
        # rb = tk.Radiobutton(self.loc, text=txt)
        rb.grid(row=r, column=c, sticky='ew')


class LablFrm(tk.LabelFrame):
    def __init__(self, parent, txt, r, c, *args, **kwargs):
        tk.LabelFrame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        self.label = tk.LabelFrame(parent, text=txt, height=100, width=620)
        self.label.grid(row=r, column=c, padx=10)


class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        parent.title("GUI")
        parent.geometry('640x480+200+200')
        self.widgets()

    def widgets(self):
        LablFrm(self.parent, '0 Label Frame', 0, 0)
        LablFrm(self.parent, '1 Label Frame', 1, 0)
        LablFrm(self.parent, '2 Label Frame', 2, 0)
        RadioBut(self.parent, 'set', 3, 0)
        # lf2 = LablFrm(self.parent, '2 Label Frame', 2, 0)
        # rb2 = RadioBut(self.parent, lf2, 'set', 2, 0)
        ## rb2 = tk.Radiobutton(lf2, text='set')
        ## rb2.grid(row=0, column=0)


if __name__ == "__main__":

    root = tk.Tk()
    MainApplication(root)
    root.mainloop()

I had hoped passing a location variable as in the commented lines above might work. Even the doubly commented approach failed. Something screwy with LablFrm definitions, among other things, I imagine...

1 Answers1

0

You are placing the widgets in the wrong containers (tk.Frames).

I did not check the entire program, but this modified App class now places widgets inside your custom designed widgets:

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        self.parent = parent                               # save a reference to parent
        super().__init__(self.parent, *args, **kwargs)     # use super() and place inside parent
                                                           # your other widget classes should also be modified this way
        self.widgets()
        self.pack()                                        # use geometry manager pack on self (tk.Frame subclass)

    def widgets(self):
        LablFrm(self, '0 Label Frame', 0, 0).grid(row=0, column=0)  # place inside self, and apply geometry manager grid
        LablFrm(self, '1 Label Frame', 1, 0).grid(row=0, column=1)  # same
        LablFrm(self, '2 Label Frame', 2, 0).grid(row=0, column=2)  # same
        RadioBut(self, 'set', 3, 0).grid(row=0, column=3)           # same
        lf2 = LablFrm(self, '2 Label Frame', r=4, c=0)              # same
        lf2.grid(row=1, column=0)                                   # apply geometry manager grid
        rb2 = RadioBut(self, lf2, text='set', r=4, c=1)             # same
        rb2.grid(row=1, column=1)                                   # apply geometry manager grid
        rb22 = tk.Radiobutton(lf2, text='set')                      # place inside lf2 widget
        rb22.grid(row=2, column=2)                                  # apply geometry manager grid


if __name__ == "__main__":

    root = tk.Tk()
    root.title("GUI")                 # avoid modifying a parent class inside a child class
    root.geometry('640x480+200+200')  # moved these 2 lines out of App
    MainApplication(root)
    root.mainloop()
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80