简体   繁体   中英

Using widget in a tab of ttk.Notebook?

I'm trying to display a simple Notebook widget with two tabs. Here's the code of what I tried without all the unnecessary code in between:

import tkinter as tk
from tkinter import ttk

color_bg = "gray20"
font = "Lucida Sans Typewriter"
DEFAULT_FONT_SIZE = 16

class Tab(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.parent = parent
        self.pack()

        self.textfield = tk.Text(
            self.parent, 
            font = (font, DEFAULT_FONT_SIZE), 
            background = color_bg, 
            bd = 10, 
            relief = tk.FLAT)

        self.textfield.pack(fill = tk.BOTH, expand = True)


class TabDisplay(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.parent = parent
        self.pack(fill = tk.BOTH, expand = True)

        self.tabholder = ttk.Notebook(parent)
        self.tabholder.pack(fill = tk.BOTH, expand = True, side = tk.TOP)

        self.viewtab = Tab(self.tabholder)
        self.edittab = Tab(self.tabholder)
        self.tabholder.add(self.viewtab, text = "View")
        self.tabholder.add(self.edittab, text = "Edit")


class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

        # Set size and position
        self.x_pos = 0
        self.y_pos = 0
        self.width = self.parent.winfo_screenwidth()
        self.height = self.parent.winfo_screenheight()
        self.parent.geometry(f"{self.width}x{self.height}+{self.x_pos}+{self.y_pos}")
        self.parent.resizable = True

        # Add Widgets
        self.tabdisplay = TabDisplay(self)


if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).pack(fill = tk.BOTH, expand = True)
    root.mainloop()

When I run this, it does not display an actual notebook. It just displays the two tabs below eachother. However, when I replace Tab(self.tabholder) with tk.Frame(self.tabholder) it functions perfectly (apart from not using the contents of the Tab() class).

Why does it not display correctly with my Tab() class? I have never had issues with classes that inherit from tk.Frame until I started using ttk.Notebook() . Is it an issue with ttk?

EDIT: I have since found out that the actual culprit is the Text widget within the Tab() class. Now my question is why does adding a widget break the notebook?

Think of a frame like a box. You create a box, and then you put widgets inside the box. Only, in your case you're creating widgets in the box but placing them outside the box when you add them to self.parent rather than self .

When you create a class that inherits from tk.Frame , every widget inside that class should be a direct child or descendant of self . In doing so, an instance of the class becomes a self-contained object that can be the child of any other widget.

For example:

class Tab(tk.Frame):
    def __init__(self, parent):
        ...
        self.textfield = tk.Text(
            self, 
            ...

... and:

class TabDisplay(tk.Frame):
    def __init__(self, parent):
        ...
        self.tabholder = ttk.Notebook(self)
        ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM