简体   繁体   中英

Tkinter change number in multiple labels

I am making a program that lets a user input a flower type, and it will make a new row with row#, name, and days remaining before it dies. At the moment the UI is a bit messy and code could be improved a lot but that's not the point. I would like to know how I would go about making multiple new labels that I can change the days remaining with the click of a button.

Here is my code so far:

It runs ok but only the lastest made row can be changed, this is because every time one is made, the last one can't be edited anymore, and that's what I want to change.

from tkinter import *

#Flower Types

flowers_days = {
    "peony": 1,
    "rose": 2,
    "daffodil": 3,
    "dandelion": 4,
    "lavender": 5
}
day_change = {}

#Variables
day = 1
days_left = 5
row_Num = 0
name = ""

#Commands


def new_flower():
    #make a new line with the new flower
    global row_Num
    global days_left
    global name
    global new_row

    row_Num += 1

    name = str(clicked.get())
    print("Test:" + name)

    days_left = flowers_days[clicked.get()]

    day_change[days_left] = int(row_Num)

    new_row = Label(main_Frame, text=str(row_Num)+"    "+name+"    " + str(days_left))
    new_row.pack()

    return new_row


def next_day():
    global days_left
    global name
    days_left -= 1
    new_row.config(text=str(row_Num)+"    "+name+"    " + str(days_left))


root = Tk()

new_row = Label()

clicked = StringVar()
clicked.set("No option Selected")

#FLOWER TYPE
flower_Type_Frame = LabelFrame(root, text="New Flowers", padx=5, pady=5)
flower_Type_Frame.grid(row=0, rowspan=4, column=0, columnspan=2, padx=10, pady=10)
flower_Type_Label = Label(flower_Type_Frame, text="Flower Type:")
flower_Type_Label.grid(row=0, column=0, columnspan=2, padx=5, pady=5)

flower_Type_Drop = OptionMenu(flower_Type_Frame, clicked, """
No option Selected
""", "peony", "rose", "daffodil", "dandelion", "lavender")
flower_Type_Drop.grid(row=1, column=0, columnspan=2, pady=5, padx=5)

flower_Type_Submit = Button(flower_Type_Frame, text="Submit", padx=10, pady=10, command=new_flower)
flower_Type_Submit.grid(row=2, column=0, columnspan=2, rowspan=2)


#Empty slot
space_Frame = LabelFrame(root, text="Empty", padx=5, pady=5)
space_Frame.grid(row=0, rowspan=4, column=3, columnspan=2, padx=10, pady=10)
space_Fill = Label(space_Frame, text="Space          ").grid(row=0, column=0)


#Day Pass
day_Pass_Frame = LabelFrame(root, text="Day Pass", padx=5, pady=5)
day_Pass_Frame.grid(row=0, rowspan=2, column=6, columnspan=4, padx=10, pady=10)
day_Pass = Button(day_Pass_Frame, text="Next Day", padx=10, pady=10, command=next_day)
day_Pass.grid(row=0, rowspan=2, column=3, columnspan=2)


#Row Delete


#Main stuff
main_Frame = LabelFrame(root, text="Flowers In Stock", padx=5, pady=5)
main_Frame.grid(row=5, column=0, columnspan=7, padx=10, pady=10)
header = Label(main_Frame, text="   Row #   /   Flower Type   /   Days Remaining   ", padx=5, pady=5)
header.pack(padx=5, pady=5)


root.mainloop()

Once this is sorted I also plan on making it to have a remove row button, so the row numbers need to be able to be changed too if possible.

Thanks for any help.

You're keeping only one 'days_left' information (in a global variable), but you need to keep one for each flower. So your main data structure needs to be a list of flowers, and you should remove the 'global' statements for days_left, name, new_row, as that information needs to be secific to each flower.

Add this to the global scope (just before the new_flower() definition):

# List of [name, days_left, label], one per flower
flowers = []

In the new_flower() function, add the newly-created flower to the list with 'append':

new_row = Label(main_Frame, text=str(row_Num)+"    "+name+"    " + str(days_left))
new_row.pack()
flowers.append([name, days_left, new_row])

The next_day function should look like this:

def next_day():
    for i, f in enumerate(flowers):
        # f is a 3-element list [name, days_left, label]
        f[1] -= 1
        name, days_left, label = f
        label.config(text=str(i+1)+"    "+name+"    " + str(days_left))

The 'enumerate' call iterates over a list, returning both the current index in the list (in 'i') and the current list item (in 'f'). The index gives you the row number.

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