TomSchimansky / CustomTkinter

A modern and customizable python UI-library based on Tkinter
MIT License
10.84k stars 1.02k forks source link

Delete widget from grid does not update grid size #2271

Closed P3rdigas closed 4 months ago

P3rdigas commented 5 months ago

I'm doing an app using this library where the user can load an file and that will populate CTkEntries inside a frame in a grid layout. However, when the user delete the files, i wanna clear the text inside the Entries and delete the extra ones, but the size of the grid is not updated.

Code:

frame_widgets = self.data_entry_scroll_frame.winfo_children()
            for widget in frame_widgets:
                row_index = widget.grid_info()["row"]
                col_index = widget.grid_info()["column"]

                if row_index > 3 or col_index > 2:
                    if type(widget) != customtkinter.CTkButton:
                        widget.destroy()
                else:
                    if type(widget) == customtkinter.CTkEntry:
                        widget.delete(0, END)

            num_cols = self.data_entry_scroll_frame.grid_size()[0]
            num_rows = self.data_entry_scroll_frame.grid_size()[1]
            print(f"Num_Cols: {num_cols} Num_Rows: {num_rows}")

Result: Num_Cols: 7 Num_Rows: 22

AshhadDevLab commented 4 months ago

Description:

The issue is here:widget.delete(0, END). The misunderstanding is that widget.delete(0, END) is used by the vanilla tkinter library, customtkinter utilizes widget.delete(first_index, last_index) to delete the whole data inside an entry you can use widget.delete(0, len(widget.get()))

Solution:

So instead of using the above code use this:

frame_widgets = self.data_entry_scroll_frame.winfo_children()
for widget in frame_widgets:
    row_index = widget.grid_info()["row"]
    col_index = widget.grid_info()["column"]

    if row_index > 3 or col_index > 2:
        if type(widget) != customtkinter.CTkButton:
            widget.destroy()
    else:
        if type(widget) == customtkinter.CTkEntry:
            widget.delete(0, len(widget.get()))

num_cols = self.data_entry_scroll_frame.grid_size()[0]
num_rows = self.data_entry_scroll_frame.grid_size()[1]
print(f"Num_Cols: {num_cols} Num_Rows: {num_rows}")
P3rdigas commented 4 months ago

I think i made a mistake when i wrote this issue, i wanna clear (delete the string) of some entries and the destroy the rest of them. The deletion of the data inside the Entries works, so i assume the issue occurs when i try to destroy the entries. I forgot to include that the const END was imported from tkinter(from tkinter import filedialog, END).

This is a look when i import the file and the data is populated: image

Now, after deleting the file, the entries are cleared and the rest are destroyed visually, like: image

However, with the code above, the result of the grid is: Num_Cols: 7 Num_Rows: 22

AshhadDevLab commented 4 months ago

Oh, so this is better plus I didn't know that you were importing the delete function from tkinter. Sorry for that.

AshhadDevLab commented 4 months ago

so according to your given code I cam up with this:

frame_widgets = self.data_entry_scroll_frame.winfo_children()
for widget in frame_widgets:
    row_index = widget.grid_info()["row"]
    col_index = widget.grid_info()["column"]

    if row_index > 3 or col_index > 2:
        if not isinstance(widget, customtkinter.CTkButton):
            widget.destroy()
    else:
        if isinstance(widget, customtkinter.CTkEntry):
            widget.delete(0, len(widget.get()))

num_cols = self.data_entry_scroll_frame.grid_size()[0]
num_rows = self.data_entry_scroll_frame.grid_size()[1]
print(f"Num_Cols: {num_cols} Num_Rows: {num_rows}")

Try this and lemme know! Or maybe add a bigger code or simply send a link of your GITHUB repo we'll take a look at it

P3rdigas commented 4 months ago

Unfornately that code doesn't seem to fix it. Here is the link of my repo https://github.com/P3rdigas/AutoContract. For the frame i'm using a third party libary, CTkXYFrame, found here: https://github.com/Akascape/CTkXYFrame. Initially i suspected that the issue was related with the grid layout, but i'm testing if the issue could be related with the CTkXYFrame library, but if you found any issue with my code let me know!

P3rdigas commented 4 months ago

I think i found the issue. The buttons for adding columns and rows have a property of rowspan and columnspan. When the data is imported these properties are updated. My problem was that i wanted to update these properties with the size of the grid, however the grid size is influenced by them, meaning that when data is imported the columnspan is updated to 21 and the rowspan to 7. When the entries are destroyed these properties are not updated and the grid size remain 7 and 21, but if inside the for loop i set the columnspan and rowspan of the buttons to 1, in the end the real size of the grid will be shown. Thanks a lot for your time and your help!