PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, October 26, 2022

[FIXED] How can I "reset" the size of a Window on Tkinter when using Notebook?

 October 26, 2022     oop, python, tkinter, user-interface     No comments   

Issue

I know this has been asked before but none of the solutions that I've seen so far seem to work.

So here's the exact case: I'm building an app that has 3 different tabs (using ttk.Notebook). The initial contents of the 3 tabs is different: the second is the smallest and the third is he biggest.

Now here comes the issue (I'm using grid, btw): when I change from the first to the second, there is an extra empty space (because the content of the first Tab is a little bigger than the one of the second, and the same happens when I go from the third to the second/first, so after using the third tab and changing to another one, the size stays as if I still was in the third.

I add some of the code that I'm using, but since I'm not sure what is going wrong, I'll let you ask for whatever extra code you might need to help me find the solution.

# Tk modules
import tkinter as tk
from tkinter import ttk

# # define main()
def main():
    app = App()
    MainWindow(app)
    app.mainloop()


# Frame for data input
class RegisterChooseType(ttk.Frame):
    def __init__(self, container):
        # Inheritance
        super().__init__(container)
        self.container = container

        # Var for selection
        self.selected_value = tk.IntVar()

        # Options
        self.options = {"padx": 10, "pady": 10}

        # Doc types
        self.doc_types = ("Incoming Bill", "Outgoing Bill", "Contract", "Other")

        # Labels
        self.barcode_label = ttk.Label(self, text="Barcode:").grid(
            row=0, column=0, sticky="EW", **self.options
        )

        self.doc_type_label = ttk.Label(self, text="Document type:").grid(
            row=0, column=2, sticky=tk.W, **self.options
        )

        # Entries
        self.barcode_entry = ttk.Entry(self)
        self.barcode_entry.grid(row=0, column=1, sticky="EW", **self.options)

        self.grid()

    def submit(self):
        self.current_dict["func"](self, self.current_frame)


class DeleteTab(ttk.Frame):
    def __init__(self, container):
        # Inheritance
        super().__init__(container)

        # self.columnconfigure(0, weight=1)
        # self.columnconfigure(1, weight=1)

        self.options = {"padx": 10, "pady": 10}

        ## Type Barcode
        # Label
        self.barcode_label = ttk.Label(self, text="Barcode:").grid(
            row=0, column=0, sticky="EW", **self.options
        )
        # Entries
        self.barcode_entry = ttk.Entry(self)
        self.barcode_entry.grid(row=0, column=1, sticky="EW", **self.options)

        # self.pack(fill="x")
        self.grid(sticky="W")


class ViewTab(ttk.Frame):
    def __init__(self, container):
        # Inheritance
        super().__init__(container)
        self.container = container

        self.options = {"padx": 10, "pady": 10}

        # Doc types
        self.doc_types = ("Incoming Bill", "Outgoing Bill", "Contract", "Other")

        ## Type Barcode
        # Labels
        # Barcode
        self.barcode_label = ttk.Label(self, text="Barcode:")
        self.barcode_label.grid(row=0, column=0, sticky="EW", **self.options)

        # Document type
        self.doc_type_label = ttk.Label(self, text="Document Type:")
        self.doc_type_label.grid(row=0, column=2, sticky="EW", **self.options)

        # Entries
        # Barcode
        self.barcode_entry = ttk.Entry(self)
        self.barcode_entry.grid(row=0, column=1, sticky="EW", **self.options)

        # Document type
        self.doc_type_comb = ttk.Combobox(self)
        self.doc_type_comb["state"] = "readonly"  # Doesn't allow new entries
        self.doc_type_comb["values"] = self.doc_types
        self.doc_type_comb.grid(
            row=0, column=3, columnspan=3, sticky=tk.EW, **self.options
        )

        ## View Button
        self.viewSubmitButton = ttk.Button(
            self, text="View", command=lambda: print("View")
        )
        self.viewSubmitButton.grid(
            column=4,
            row=self.grid_size()[0],
            sticky="EW",
            **self.options,
        )

        # New LabelFrame
        self.deliver_view_LabelFrame = ttk.LabelFrame(self)
        self.deliver_view_LabelFrame["text"] = "View Document"
        self.deliver_view_LabelFrame.grid(
            row=1,
            columnspan=self.grid_size()[0],
            column=0,
            sticky="ew",
            padx=10,
            pady=10,
        )
        # Inside LabelFrame

        ##TreeView
        self.dataDisplay = ttk.Treeview(self.deliver_view_LabelFrame, show="")
        self.dataDisplay.pack(fill="x", **self.options)

        self.grid(sticky="ews")


# Create window
class MainWindow:
    def __init__(self, container):
        self.container = container

        ## Create Parent
        self.tab_parent = ttk.Notebook()
        self.tab_parent.enable_traversal()

        # Create tab frames
        self.tab_register = ttk.Frame(self.tab_parent)
        self.tab_view = ttk.Frame(self.tab_parent)
        self.tab_delete = ttk.Frame(self.tab_parent)

        # Adding the tabs to the main object (self.tab_parent)
        self.tab_parent.add(self.tab_register, text="Register Documents")
        self.tab_parent.add(self.tab_delete, text="Delete Documents")
        self.tab_parent.add(self.tab_view, text="View Documents")

        # Create empt variables
        self.current_tab = None
        self.last_tab = None

        # Focus on barcode
        # self.register.barcode_entry.focus()

        self.tab_parent.bind("<<NotebookTabChanged>>", self.on_tab_change)

        # Pack notebook
        # self.tab_parent.pack(expand=True, fill="x", side="left")
        self.tab_parent.grid(sticky="e")

    ## Triggers when changing tabs
    def on_tab_change(self, event):
        if self.current_tab != None:
            self.current_tab.destroy()

        # Get the current tab name
        selected = event.widget.tab("current")["text"]

        # Create frame depending on Tab chosen
        if selected == "Register Documents":
            self.current_tab = RegisterChooseType(self.tab_register)
            self.clean_tabs()
            self.last_tab = self.current_tab

        elif selected == "Delete Documents":
            self.current_tab = DeleteTab(self.tab_delete)
            self.clean_tabs()
            self.last_tab = self.current_tab

        elif selected == "View Documents":
            self.current_tab = ViewTab(self.tab_view)
            self.clean_tabs()
            self.last_tab = self.current_tab

        self.current_tab.barcode_entry.focus()

    def clean_tabs(self):
        if self.last_tab != None:
            # for widget in self.last_tab.winfo_children():
            #     # for widget in self.last_tab.grid_slaves():
            #     widget.destroy()
            self.last_tab.destroy()

            # ## INTERESTING
            # self.last_tab.blank = ttk.Label(self.last_tab, text="1")
            # self.last_tab.blank.grid()
            # print(self.last_tab.grid_slaves()[0].cget("text"))
            # self.container.geometry("1x1")
            self.tab_parent.update()
            # self.container.update()
        # self.container.geometry("")
        # self.container.update()


# Creatig App
class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.geometry("")
        self.title("iMPETU Document Handling v.0.1.0a")
        self.resizable(0, 0)


if __name__ == "__main__":
    main()

I tried deleting one by one the widgets of the current tab before changing to another one, also doing the same AFTER changing to the new tab (that's why I have 2 variables for current and last tab), I also tried leaving an empty tag (supposedly 0 pixels) but that would push all the contents down.

I tried withdraw, deiconify just out of curiosity, I also tried using self.container.update() to update the main window, also tried changing the geometry to "1x1" in the clean_tabs function and then changing again to "" at the end of the on_tab_change and see if that would maybe force it to resize but none of that worked.


Solution

You can resize all the frames (parents of instances of RegisterChooseType, DeleteTab and ViewTab) to size 1x1 at the beginning of clean_tabs():

def clean_tabs(self):
    for tab in self.tab_parent.tabs():
        # tab is the name of the frame
        # so get the widget using .nametowidget()
        # then call .config(width=1, height=1) to resize the frame to size 1x1
        self.tab_parent.nametowidget(tab).config(width=1, height=1)
    ...


Answered By - acw1668
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

1,217,854

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © 2025 PHPFixing