0

I am currently trying to figure out how to do the following:

I have created a window that contains a table(frame) with Entry widgets, Label widgets, checkbox widgets and button widgets using for-loops. The window also has two buttons (outside the table) that allow the user to either insert new rows or delete them. Up to this point the app works very well. However I am having a hard time figuring out how to create two more functions that run with the buttons created in the for-loop that move an specific row up or down.

The 'UP' button for example, in row 5, needs to move the row 5 of entry widgets up to row 4, while bringing the row previusly positioned in row 4 to row 5. See below:

How it looks BEFORE pressing "up" button in row 5 (click here)

How it looks AFTER pressing "up" button in row 5 (click here)

I have figured out how to swap the entry widgets, however what happens after when I tried to move row 4 to row 3 and row 3 to 4 after succesfully doing row 5 and 4, this happens, see below:

what happens AFTER pressing "up" button in row 4 (click here)

Also I would like stop row #1 to move up since it is the first row, there is nowhere to go, however I am having an issue making a condition to avoid that. See below:

What happens when pressing "up" button in row 1

I also would appreciatte very much that if someone has a better solution than the button up and down for dyanmically re-aaranging the rows in these table, please advise. I am opened to anything. For exmaple I have been reading about the drag and drop method, however it seems a bit more complicated and I do notknow if it's possible to do/use on this layout

import customtkinter
# from functools import partial

customtkinter.FontManager.load_font("Industry-Book.otf")
customtkinter.FontManager.load_font("Industry-Medium.otf")
customtkinter.FontManager.load_font("Industry-Demi.otf")


def append():
    global row, rows,currenth
    row = rows
    for column in range(columns):
        index = (row, column)
        e = customtkinter.CTkEntry(framedash, validate="key",justify='c',fg_color='#27333B',border_color='#D1D3D4')#, validatecommand=self.vcmd)
        e.grid(row=row+1, column=column+1, stick="nsew")
        _entry[index] = e
    l1 = customtkinter.CTkLabel(framedash, text=row + 1, font=("Industry-Medium", 14),bg_color='#8F8F8F',width=40)  # setting a lable/text
    l1.grid(row=row+1, column=0, columnspan=1, padx=1, pady=1,stick="nsew")
    cb = customtkinter.CTkCheckBox(framedash, text='', width=0)
    cb.grid(row=row + 1, column=5, columnspan=1, padx=1, pady=1, stick="nsew")
    downbutton = customtkinter.CTkButton(framedash, text='DW', width=20, height=20)
    downbutton.grid(row=row + 1, column=6, columnspan=1, padx=1, pady=1, stick="nsew")
    upbutton = customtkinter.CTkButton(framedash, text='UP', width=20, height=20)
    upbutton.grid(row=row + 1, column=7, columnspan=1, padx=1, pady=1, stick="nsew")

    _entry1[index] = l1
    _entry2[index] = cb
    _entry3[index] = downbutton
    _entry4[index] = upbutton

    currenth = currenth + 30
    dashboard.geometry(f'450x{currenth}')
    rows += 1
    print(_entry)


def addrow():
    append()


def delete():
    global row, rows, currenth
    if rows==1:
        return False
    else:
        row = rows-1
        for column in range(columns):
            index = (row, column)
            _entry[index].grid_remove()
        _entry1[index].grid_remove()
        _entry2[index].grid_remove()
        _entry3[index].grid_remove()
        _entry4[index].grid_remove()
        currenth = currenth - 30
        dashboard.geometry(f'450x{currenth}')
        rows -= 1

def deleterow():
    delete()


def up(row): #FUNCTION I AM TRYING TO FIGURE OUT

    for column in range(columns):

        index=(row,column)
        _entry[row,column].grid_configure(row=row, column=column+1)
        _entry[row-1,column].grid_configure(row=row+1, column=column+1)



currenth=380
dashboard = customtkinter.CTk(fg_color='#27333b')
dashboard.geometry(f"450x{currenth}") #size of window
dashboard.title('Itipack Systems Cals') #tittle of the window
dashboard.attributes('-topmost', True)  # note - before topmost
dashboard.resizable(False, False)
dashboard.after(201, lambda: dashboard.iconbitmap('Itipack_icon_cmyk_rev_l.ico'))

_entry = {}
_entry1 = {}
_entry2 = {}
_entry3 = {}
_entry4 = {}
rows=9
columns =2
table = [columns,rows]

framedash = customtkinter.CTkFrame(dashboard,width=600,height=600,fg_color='#27333b')
framedash.grid(row=2,column=0,padx=10,pady=10,columnspan=columns+4,rowspan=rows+1,sticky='')


c1 = customtkinter.CTkLabel(framedash,text='FUNCTION',font=("Industry-Medium",14),bg_color='grey',width=60) #setting a lable/text
c1.grid(row=0, column=1, columnspan=1, padx=1, pady=1,sticky='nesw') #location?

c2 = customtkinter.CTkLabel(framedash,text='DURATION',font=("Industry-Medium",14),bg_color='grey',width=40) #setting a lable/text
c2.grid(row=0, column=2, columnspan=1, padx=1, pady=1,sticky='nesw') #location?



for row in range(rows):
    l1 = customtkinter.CTkLabel(framedash, text=row+1, font=("Industry-Medium",14),bg_color='#8F8F8F',width=40)  # setting a lable/text
    l1.grid(row=row+1, column=0, columnspan=1, padx=1, pady=1, stick="nsew")
    cb= customtkinter.CTkCheckBox(framedash,text='',width=0)
    cb.grid(row=row+1, column=5, columnspan=1, padx=1, pady=1, stick="nsew")
    downbutton = customtkinter.CTkButton(framedash,text='DW',width=20,height=20) #lamda expression to give the command to every button
    downbutton.grid(row=row + 1, column=6, columnspan=1, padx=1, pady=1, stick="nsew")
    upbutton = customtkinter.CTkButton(framedash,text='UP',width=20,height=20,command=lambda row=row:up(row))
    upbutton.grid(row=row + 1, column=7, columnspan=1, padx=1, pady=1, stick="nsew")

    for column in range(columns):
        index = (row, column)
        e = customtkinter.CTkEntry(framedash, validate="key",justify='c',fg_color='#27333B',border_color='#D1D3D4')#, #validatecommand=self.vcmd)
        e.grid_configure(row=row+1, column=column+1,padx=1, pady=1, stick="nsew")
        _entry[index] = e
    _entry1[index] = l1
    _entry2[index] = cb
    _entry3[index]= downbutton
    _entry4[index]=upbutton

# adjust column weights so they all expand equally
for column in range(columns):
    framedash.grid_columnconfigure(column, weight=0)
# designate a final, empty row to fill up any extra space
framedash.grid_rowconfigure(rows, weight=0)

button1 = customtkinter.CTkButton(dashboard, width=50, height=50, text='A', font=("Industry-Medium", 16),
                                  corner_radius=1, fg_color='#00AAE9',
                                  command=addrow)  # , command=calculate)
button1.grid(row=0, column=0, padx=5, pady=5, sticky='e')


button1 = customtkinter.CTkButton(dashboard, width=50, height=50, text='D', font=("Industry-Medium", 16),
                                  corner_radius=1, fg_color='#00AAE9',
                                  command=deleterow)  # , command=calculate)
button1.grid(row=0, column=1, padx=5, pady=5, sticky='w')

button1 = customtkinter.CTkButton(dashboard, width=50, height=50, text='S', font=("Industry-Medium", 16),
                                  corner_radius=1, fg_color='#00AAE9')  # , command=calculate)
button1.grid(row=0, column=2, padx=5, pady=5)

label12=customtkinter.CTkEntry(dashboard,width=50,height=30,justify='c')
label12.grid(row=0, column=4, padx=5, pady=5,sticky='w')

label12=customtkinter.CTkLabel(dashboard,text='# STRAPS',font=("Industry-Medium", 16))
label12.grid(row=0, column=3, padx=5, pady=5,sticky='e')

dashboard.grid_columnconfigure(0, weight=1)
dashboard.grid_columnconfigure(1, weight=1)
dashboard.grid_columnconfigure(2, weight=1)
dashboard.grid_columnconfigure(3, weight=1)
dashboard.grid_columnconfigure(4, weight=1)
dashboard.grid_columnconfigure(5, weight=1)
dashboard.mainloop()



RafaelTech
  • 19
  • 7
  • straight away, having made similar errors with `tkinter` related apps, i can tell you that using `global` will make the code messy (consider it poor practice) if it grows. there are get and set methods what will be easier in the long run. – D.L Jun 29 '23 at 18:27
  • hello, thank you for your input. Do you mind providing an example?Thanks @D.L – RafaelTech Jun 29 '23 at 19:37
  • Why do you have the for loop inside `append()`? – acw1668 Jun 30 '23 at 01:21
  • Because I have two entries in each row. If there is no for loop, when appending/adding a row, the funtion adds only one entry widgetl and leaves the one beside it empty. Same thing I would like to increase the amount of entry widgets in a row and want to append an extra row, I need a for loop so that it does not only add one single entry widget but whatever the number of columns i tell it to be. @acw1668 – RafaelTech Jun 30 '23 at 13:19
  • Then you should include the entries creation within the for loop, not other widgets like the label, checkbox and the buttons. – acw1668 Jun 30 '23 at 16:25
  • That makes sense!. Thank you very much @acw1668 – RafaelTech Jun 30 '23 at 16:36

1 Answers1

0

You need to update the dictionary _entry as well:

def up(row): #FUNCTION I AM TRYING TO FIGURE OUT
    # don't move first row up
    if row > 0:
        for column in range(columns):
            #index=(row,column)  # not used
            _entry[row,column].grid_configure(row=row, column=column+1)
            _entry[row-1,column].grid_configure(row=row+1, column=column+1)
            # swap _entry dictionary
            _entry[row,column], _entry[row-1,column] = _entry[row-1,column], _entry[row,column]
acw1668
  • 40,144
  • 5
  • 22
  • 34