External window is empty with "tk.Toplevel" and "parent"

When I click on a label to open an external window (tertiary.py), the window opens normally but is empty inside. I don't get errors, but I don't see Tkinter widgets and miscellaneous items.

This is the secondary window where there is the label on which I click in order to open an external window. I add, for information purposes only, that this window is called secondary because it is displayed in a frame (with a vertical menu on the left) where the main window is called home = tk.Tk(). The secondary window opens and displays correctly in the frame.

Inside the secondary window there is the label thanks to which I want to open an external window (not in the frame) called tertiary

How can I solve?

secondary.py

import tkinter as tk
from tkinter import *
from tkinter import ttk

import other_options
from other_options import form_other_options

class Page2(tk.Frame):
    def __init__(self, master, **kw):
        super().__init__(master, **kw)

        self.configure(bg='white')
        bar1=Frame(self, width=2200, height=35, background="#960000", highlightbackground="#b40909", highlightthickness=0) #grigio chiaro #b40909
        bar1.place(x=0, y=0)

        other_options = Label(self, text="Other Options", bg="#960000", foreground='white', font='Ubuntu 10')
        other_options.place(x=1025, y=7)
        other_options.bind("<Button-1>", lambda event: other_options.form_other_options(self))

tertiary.py

from tkinter import *
from tkinter import ttk
import tkinter as tk

def form_other_options(parent):

    other_options = tk.Toplevel(parent)
    other_options.title("Other options")
    other_options.geometry("1000x800")
    other_options.config(bg="white")
    other_options.state("normal")

    other_options.transient(parent)


    class checkbox():
        def __init__(self, master, **kw):
            super().__init__(master, **kw)

            labelframe1 = LabelFrame(self, text="checkbox", width=600,height=190, bg="white", foreground='#e10a0a')
            labelframe1.place(x=10, y=13)

            Checkbutton1 = IntVar()

            Button1 = Checkbutton(self, text = "option1",
                    variable = Checkbutton1,
                    onvalue = 1,
                    offvalue = 0,
                    height = 2,
                    width = 10)

            Button1.pack()

    other_options.mainloop()

Solution 1:

The first reason why the window is empty is that you never create an instance of the class checkbox, so the code that creates the widgets never runs.

So, the first step is to make sure you create an instance of that class:

other_options = tk.Toplevel(parent)
...
cb = checkbox(other_options)

When you do that, you will discover other bugs in your code. The first positional argument when creating a tkinter widget must be another widget. If you want the widget to be inside a Toplevel, the parent needs to be the toplevel or a descendant. You're using self which isn't a widget at all.

A simple fix is to use master instead of self, since you're passing the toplevel window as the master parameter:

labelframe1 = LabelFrame(master, ...)
Button1 = Checkbutton(master, ...)

You also need to remove the call to other_options.mainloop(). Unless there is a very compelling reason to do otherwise, an entire application should only call mainloop() exactly once.


There are other problems in the code that, strictly speaking, aren't related to the question being asked. For example, you're importing tkinter twice: once as import tkinter as tk and once as from tkinter import *. You only need to import tkinter once, and PEP8 recommends to use the first form:

import tkinter as tk

You'll need to add the prefix tk. to every place where you call a tkinter function. This will help make your code easier to understand and helps prevent pollution of the global namespace.

You also should use PEP8 naming standards. Specifically, class names should begin with an uppercase character. This will also make your code easier to understand.

There's also no reason why your checkbox class should be indented. You should move it out of the function.

Also, instead of checkbox not inheriting from anything, and then creating a LabelFrame, you should just inherit from LabelFrame. That way you can use your class more like a real widget, and would enable you to use self rather than master when creating the other widgets.

class Checkbox(tk.LabelFrame):
    def __init__(self, master, **kw):
        super().__init__(master, **kw)
        ...
        button1 = tk.Checkbutton(self, ...)
        ...

There are probably other problems, but those are the most obvious.