Home > Net >  How to make python tkinter treeview widget to fill empty row and column spaces on grid?
How to make python tkinter treeview widget to fill empty row and column spaces on grid?

Time:01-06

I have a window to display multiple treeview widgets. Currently there are some empty row spaces below the treeview when I expand it and I'm not sure on how to fill the empty spaces below dynamically when I expand the window. I have tried adjusting the rowspan/columnspan options but could not get the desired output as described in image below. I have also included a reproduceable code below for testing my program. Please help to advise on which part I need to make changes. Thanks!

Window Layout

import shutil
import tkinter as tk
import tkinter.ttk as ttk
import tempfile
import zipfile, re, os
from tkinter import *
from tkinter import filedialog
from pathlib import Path
import tkinter.messagebox
from fpdf import FPDF
from datetime import datetime, timedelta
import ctypes

DEPTH = 2
EXCLUDES = {'__MACOSX', 'resources'}

class HomePage(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)
        self.notebook = ttk.Notebook()  # Create a notebook widget
        self.add_tab1()
        self.notebook.grid(row=0)
        self.notebook.pack(expand=1, fill="both")

    def add_tab1(self):
        tab1 = tab_one(self.notebook)
        self.notebook.add(tab1, text="Home")

class data_table(object):
    def __init__(self, site, panels_count, tev_count):
        self.site = site
        self.panels_count = panels_count
        self.tev_count = tev_count


class tab_one(Frame):
    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)
        # Creating frames on the window/canvas for the first tab
        frame_selectfile = tk.LabelFrame(self, text="Step 1: Zip File Extraction ", bd=6)  # Frame1 on the window/canvas
        frame_selectfile.grid(column=0, row=0, padx=10, pady=10, sticky='NSEW')  # Positioning frame1
        frame_selectfile.configure(borderwidth=1)
        self.grid_columnconfigure(1, weight=1)  # Configuring the column for the main window/canvas
        self.grid_rowconfigure(1, weight=1)  # Configuring the row for the main window/canvas

        frame_checkpd = tk.LabelFrame(self, text="Step 2: Check PD ", bd=6)  # Frame2 on the window/canvas
        frame_checkpd.grid(column=1, row=0, padx=10, pady=10, sticky='NSEW')  # Positioning frame2
        frame_checkpd.configure(borderwidth=1)
        self.grid_columnconfigure(1, weight=1)  # Configuring the column for the main window/canvas
        self.grid_rowconfigure(1, weight=1)  # Configuring the row for the main window/canvas

        #Frame to display data in treeview
        frame_tree = tk.LabelFrame(self, text="PD Results ", bd=6)  # Frame2 on the window/canvas
        frame_tree.grid(column=0, row=1, columnspan=2, rowspan=2,  padx=10, pady=10, sticky='NSEW')  # Positioning frame2
        frame_tree.configure(borderwidth=1)
        self.grid_columnconfigure(1, weight=1)  # Configuring the column for the main window/canvas
        self.grid_rowconfigure(1, weight=1)  # Configuring the row for the main window/canvas

        # Initializing all variables in frame_selectfile
        file_ID = tk.StringVar()
        location_id = tk.StringVar()
        unzip_status = tk.StringVar()
        tmpdir = tempfile.TemporaryDirectory().name
        f_tem_sdir = open(os.getcwd() "\\temp_dir.txt", "w")
        f_tem_sdir.write(tmpdir)
        f_tem_sdir.close()
        zip_filename = tk.StringVar()
        site_id = tk.StringVar()
        site_id.set("0")
        data_table_list = []

        middleframe = tk.LabelFrame(frame_selectfile, bd=5)
        databaseView = ttk.Treeview(middleframe, selectmode="browse")
        label_filename = tk.Label(frame_selectfile, text=" ", width=10, relief='flat').grid(column=0, row=1, padx=5,
                                                                                            pady=5, sticky='NW')
        label_filelocation = tk.Label(frame_selectfile, text="File Location:", width=12, relief='flat').grid(column=0,
                                                                                                             row=2,
                                                                                                             padx=5,
                                                                                                             pady=5,
                                                                                                             sticky='NW')

        filename_Entry = tk.Label(frame_selectfile, width=52, textvariable=file_ID)
        filename_Entry.grid(column=1, row=1, padx=5, pady=5, sticky='NW')
        filename_Entry.configure(state='normal')

        filelocation_Entry = tk.Entry(frame_selectfile, width=63, textvariable=location_id)
        filelocation_Entry.grid(column=1, row=2, padx=5, pady=5, sticky='W')
        filelocation_Entry.configure(background='palegreen', foreground='black')

        unzip_status.set("")
        label_unzipstatus = tk.Label(frame_selectfile, width=20, relief='flat', textvariable=unzip_status)
        label_unzipstatus.grid(column=1, row=5, padx=5, pady=5, sticky='NSEW')

        selectzip_button = tk.Button(frame_selectfile, width=20, text="Select Zip File",
                                     command=lambda: self.upload_action(location_id, zip_filename, tmpdir))
        selectzip_button.grid(column=1, row=3, padx=5, pady=3, ipady=3, sticky='SW')

        unzip_button = tk.Button(frame_selectfile, width=20, text="Extract",
                                 command=lambda: self.extract_nested_zip(databaseView, data_table_list,
                                                                         location_id.get(), tmpdir, zip_filename,
                                                                         site_id, False))
        unzip_button.grid(column=1, row=3, padx=5, pady=3, ipady=3, sticky='NE')

        # Creating LabelFrame in frame_unzip
        upperframe = tk.LabelFrame(frame_selectfile, bd=0)
        frame_selectfile.rowconfigure(0, weight=1)
        frame_selectfile.columnconfigure(2, weight=1)
        upperframe.grid(column=0, row=6, columnspan=2, sticky='W')

        # middleframe = tk.LabelFrame(frame_selectfile, bd=5)
        middleframe.configure(borderwidth=1)
        frame_selectfile.columnconfigure(2, weight=1)
        frame_selectfile.rowconfigure(1, weight=1)
        middleframe.grid(column=0, row=7, columnspan=2, sticky="NSEW")

        lowerframe = tk.LabelFrame(frame_selectfile, bd=0)
        lowerframe.grid(column=0, row=7)
        frame_selectfile.columnconfigure(2, weight=1)
        frame_selectfile.rowconfigure(2, weight=0)

        # Labels in frame_unzip
        label18 = tk.Label(upperframe, text="Number of sites:", relief='flat')
        label18.grid(column=0, row=0, padx=5, pady=5, sticky='W')

        site_Entry = tk.Entry(upperframe, width=61, textvariable=site_id)
        site_Entry.grid(column=1, row=0, padx=10, pady=5, sticky='E')
        site_Entry.configure(state='normal', background='palegreen', foreground='black')

        label_details = tk.Label(upperframe, text=" ", relief='flat')
        label_details.grid(column=0, row=2, padx=5, pady=0, sticky='W')

        databaseView.columnconfigure(2, weight=1)
        databaseView.grid(column=0, row=0, columnspan=2, sticky="NSEW")

        # Creating treeview in frame_unzip
        vsb = Scrollbar(middleframe, orient="vertical", command=databaseView.yview())
        hsb = Scrollbar(middleframe, orient="horizontal")

        middleframe.columnconfigure(0, weight=1)
        middleframe.rowconfigure(0, weight=1)
        databaseView["show"] = "headings"
        databaseView["columns"] = ("site", "panels", "tevs")
        vsb.configure(command=databaseView.yview)
        vsb.grid(column=1, row=0, sticky="NS")

        # Treeview column headings
        databaseView.heading("site", text="Site")
        databaseView.column("site", anchor='w', width=250)
        databaseView.heading("panels", text="Number of Panels")
        databaseView.column("panels", anchor='center', width=150)
        databaseView.heading("tevs", text="Number of TEVs")
        databaseView.column("tevs", anchor='center', width=200)

        findpd_btn = tk.Button(frame_checkpd, width=20, text="Find PDs",
                               command=lambda: self.run_pd_model_exe(tmpdir, zip_filename,parent_tree, tree))
        findpd_btn.grid(column=0, row=0, padx=5, pady=5, sticky='E')
        export_pdf_btn = tk.Button(frame_checkpd, width=20, text="Export to PDF",
                                   command=lambda: self.export_to_pdf(tmpdir, location_id.get()))
        export_pdf_btn.grid(column=1, row=0, padx=5, pady=5, sticky='E')
        find_files_btn = tk.Button(frame_checkpd, width=20, text="Clear All",
                                   command=lambda: self.clear_all_files(tmpdir,parent_tree,tree,databaseView))
        find_files_btn.grid(column=2, row=0, padx=5, pady=5, sticky='W')

        scrollbary = Scrollbar(frame_tree, orient=VERTICAL)
        scrollbarx = Scrollbar(frame_tree, orient=HORIZONTAL)

        parentframe = tk.LabelFrame(frame_checkpd, bd=0)
        frame_checkpd.rowconfigure(2, weight=1)
        frame_checkpd.columnconfigure(2, weight=1, )
        parentframe.grid(column=0, row=1, columnspan=3, sticky='W')

        # PARENT TREE
        parent_tree = ttk.Treeview(parentframe,
                                   columns=("1", "2",
                                            "3", "4",
                                            "5", "6",
                                            "7", "8"),
                                   selectmode="extended")
        parent_tree.grid(row=1, column=0, pady=2, sticky=N   S   E   W)
        #self.parent_tree.pack(expand=True, fill='both')

        vsbb = Scrollbar(parentframe, orient="vertical", command=parent_tree.yview())

        vsbb.configure(command=parent_tree.yview)
        vsbb.grid(column=2, row=1, sticky="NS")

        parent_tree.heading("#0", text="")
        parent_tree.heading("1", text="File ID")
        parent_tree.heading("2", text="Date")
        parent_tree.heading("3", text="No")
        parent_tree.heading("4", text="Engineer")
        parent_tree.heading("5", text="Station")
        parent_tree.heading("6", text="Voltage (kV)")
        parent_tree.heading("7", text="Max dB")
        parent_tree.heading("8", text="Max PD (%)")

        # parent_tree.heading("8", text = "Panel No")
        parent_tree.column('#0', stretch=YES, minwidth=0, width=5, anchor=CENTER)
        parent_tree.column('#1', stretch=YES, minwidth=0, width=130, anchor=CENTER)
        parent_tree.column('#2', stretch=YES, minwidth=0, width=130, anchor=CENTER)
        parent_tree.column('#3', stretch=YES, minwidth=0, width=130, anchor=CENTER)
        parent_tree.column('#4', stretch=YES, minwidth=0, width=130, anchor=CENTER)
        parent_tree.column('#5', stretch=YES, minwidth=0, width=130, anchor=CENTER)
        parent_tree.column('#6', stretch=YES, minwidth=0, width=130, anchor=CENTER)
        parent_tree.column('#7', stretch=YES, minwidth=0, width=130, anchor=CENTER)
        parent_tree.column('#8', stretch=YES, minwidth=0, width=130, anchor=CENTER)

        # CHILD TREE
        tree = ttk.Treeview(frame_tree,
                            columns=("1", "2", "3", "4"
                                     , "5", "6", "7", "8"
                                     , "9"),
                            selectmode="extended")
                            #yscrollcommand=scrollbary.set,
                            #xscrollcommand=scrollbarx.set)
        tree.grid(row=0, column=0, pady=2, sticky=N   S   E   W)

#         scrollbary.config(command=tree.yview)
#         scrollbary.grid(row=0, column=1, pady=2, sticky=N   S)
# 
#         scrollbarx.config(command=tree.xview)
#         scrollbarx.grid(row=2, column=0, sticky=W   E)

        tree_vsb = Scrollbar(frame_tree, orient="vertical", command=tree.yview())
        tree_hsb = Scrollbar(frame_tree, orient="horizontal")
        tree_vsb.configure(command=tree.yview)
        tree_vsb.grid(column=1, row=0, sticky="NS")

        tree.heading("#0", text="")
        tree.heading("1", text="Panel No")
        tree.heading("2", text="TEV Name")
        tree.heading("3", text="Component")
        tree.heading("4", text="Sublocation")
        tree.heading("5", text="Phase Ref Lock")
        tree.heading("6", text="dB")
        tree.heading("7", text="PRPD")
        tree.heading("8", text="Pulse Wave")
        tree.heading("9", text="PD %")

        tree.column('#0', stretch=NO, minwidth=0, width=0, anchor=CENTER)
        tree.column('#1', stretch=YES, minwidth=0, width=175, anchor=CENTER)
        tree.column('#2', stretch=YES, minwidth=0, width=175, anchor=CENTER)
        tree.column('#3', stretch=YES, minwidth=0, width=175, anchor=CENTER)
        tree.column('#4', stretch=YES, minwidth=0, width=175, anchor=CENTER)
        tree.column('#5', stretch=YES, minwidth=0, width=175, anchor=CENTER)
        tree.column('#6', stretch=YES, minwidth=0, width=175, anchor=CENTER)
        tree.column('#7', stretch=YES, minwidth=0, width=175, anchor=CENTER)
        tree.column('#8', stretch=YES, minwidth=0, width=175, anchor=CENTER)
        tree.column('#9', stretch=YES, minwidth=0, width=175, anchor=CENTER)
        
if __name__ == '__main__':
    homePage = HomePage()
    homePage.title("Waveform Identifier")  # Window title
    screen_width = homePage.winfo_screenwidth()
    screen_height = homePage.winfo_screenheight()
    width = 1600
    height = 800
    x = (screen_width / 2) - (width / 2)
    y = (screen_height / 2) - (height / 2)
    homePage.geometry("%dx%d %d %d" % (width, height, x, y))
    homePage.resizable(1, 1)
    homePage.mainloop()

CodePudding user response:

Issues found

  • Wrong row number on frame_checkpd.rowconfigure(2, weight=1), it should be row 1.
  • Wrong sticky option on parentframe.grid(column=0, row=1, columnspan=3, sticky='W'), it should be 'NSEW'.
  • missing parentframe.rowconfigure(...) and parentframe.columnconfigure(...)
  • missing frame_tree.rowconfigure(...) and frame_tree.columnconfigure(...)

Below is the required changes to achieve it:

class tab_one(Frame):
    def __init__(self, *args, **kwargs):
        ...
        parentframe = tk.LabelFrame(frame_checkpd, bd=0)
        frame_checkpd.rowconfigure(1, weight=1)    ### row 2 -> 1
        frame_checkpd.columnconfigure(2, weight=1, )
        parentframe.grid(column=0, row=1, columnspan=3, sticky='NSEW')  ### 'W' -> 'EW'

        # PARENT TREE
        parentframe.rowconfigure(1, weight=1) ### added
        parentframe.columnconfigure(0, weight=1) ### added
        ...
        # CHILD TREE
        frame_tree.rowconfigure(0, weight=1)  ### added
        frame_tree.columnconfigure(0, weight=1)  ### added
        ...

Result:

enter image description here

  • Related