[英]Change text of button with tkinter with button stored in panda data frame
我最近發現了 Tkinter 並想嘗試構建一個圖形界面來跟蹤一些項目的庫存。
我有一個熊貓表,其中包含每種產品的信息:名稱、庫存(當前可用的數量)、即將到來的(正在運送的數量)。 每個產品都有自己的按鈕,顯示產品名稱、庫存數量和正在進行的數量。
當單擊產品 + 數量 + 操作的組合時,必須調用 function 來更新為每個產品按鈕顯示的文本。 我的問題是我似乎無法正確訪問按鈕的文本來更新它。
為了有一個通用的 function 來更新產品按鈕的文本,我將按鈕保存在 pandas 數據框中,將我的產品保存在名為Button
的列中。 我想根據單擊的產品按鈕訪問按鈕df_product.loc[df_product["Name"] == df_changes.iloc[0, 0], "Button"]
,然后通過更改按鈕的['text']
。
然而這不起作用,因為存儲在Button
列中的元素的類型是<class 'pandas.core.series.Series'>
,其值是..frame.!button2
而不是<class 'tkinter.Button'>
。
我的代碼如下:
from tkinter import *
import pandas as pd
root = Tk()
# Create source df
df_product = pd.DataFrame({'Name': ['Juice', 'Cereal', 'Can'], 'In Stock': [0, 0, 0], 'Coming': [0, 0, 0], 'Button': [0, 0, 0]})
# Create & Configure root
root.geometry('720x480')
Grid.rowconfigure(root, 0, weight=1)
Grid.columnconfigure(root, 0, weight=1)
# Empty data frame to store the changes
df_changes = pd.DataFrame({'Name': ['-1'], 'Quantity': ['-1'], 'Action': ['-1']})
# Create functions
def set_name(name_product):
df_changes.iloc[0, 0] = name_product
if name_product == '-1':
recall_product['text'] = 'Make Product Selection'
else:
recall_product['text'] = 'Product selected'+'\n'+df_changes.iloc[0, 0]
check_action()
def set_quantity(amount):
df_changes.iloc[0, 1] = amount
if amount == '-1':
recall_quantity['text'] = 'Make Quantity Selection'
else:
recall_quantity['text'] = 'Quantity:'+'\n'+str(df_changes.iloc[0, 1])
check_action()
def set_action(action):
df_changes.iloc[0, 2] = action
if action == '-1':
recall_action['text'] = 'Make Action Selection'
else:
recall_action['text'] = 'Action selected'+'\n'+df_changes.iloc[0, 2]
check_action()
def check_action():
# Verify if the 3 elements (Product, Quantity adn Action) have been selected
if df_changes.iloc[0, 0] != '-1' and df_changes.iloc[0, 1] != '-1' and df_changes.iloc[0, 2] != '-1':
# If yes, verify which action needs to occure
if df_changes.iloc[0, 2] == 'In Stock':
# Update the quantity In Stock for the product selected
df_product.loc[df_product["Name"] == df_changes.iloc[0, 0], "In Stock"] += int(df_changes.iloc[0, 1])
# Update the text of the button to show the new quantity In Stock
df_product.loc[df_product["Name"] == df_changes.iloc[0, 0], "Button"]['text'] = str(df_changes.iloc[0, 0])+'\n\n'+str(int(df_product.loc[df_product["Name"] == df_changes.iloc[0, 0], "In Stock"]))+'\n\n+'+str(int(df_product.loc[df_product["Name"] == df_changes.iloc[0, 0], "Coming"]))
# Reset the table holding the buttons pressed
set_name('-1')
set_quantity('-1')
set_action('-1')
# Create & Configure frame
frame = Frame(root)
frame.grid(row=0, column=0, sticky=N+S+E+W)
frame_pad = Frame(frame)
frame_pad.grid(row=0, column=0, sticky=N+S+E+W)
frame_action = Frame(frame)
frame_action.grid(row=0, column=0, sticky=N+S+E+W)
frame_recall = Frame(frame)
frame_recall.grid(row=0, column=0, sticky=N+S+E+W)
# Create Product Button
df_product['Button'].iloc[0] = Button(frame, text=str(df_product['Name'][0])+'\n\n'+str(df_product['In Stock'][0])+'\n\n+'+str(df_product['Coming'][0]), font=('Courrier', 25), command=lambda: set_name(str(df_product['Name'][0])))
df_product['Button'].iloc[0].grid(row=0, column=0, sticky=N+S+E+W, padx=5, pady=5)
df_product['Button'].iloc[1] = Button(frame, text=str(df_product['Name'][1])+'\n\n'+str(df_product['In Stock'][1])+'\n\n+'+str(df_product['Coming'][1]), font=('Courrier', 25), command=lambda: set_name(str(df_product['Name'][1])))
df_product['Button'].iloc[1].grid(row=0, column=1, sticky=N+S+E+W, padx=5, pady=5)
df_product['Button'].iloc[2] = Button(frame, text=str(df_product['Name'][2])+'\n\n'+str(df_product['In Stock'][2])+'\n\n+'+str(df_product['Coming'][2]), font=('Courrier', 25), command=lambda: set_name(str(df_product['Name'][2])))
df_product['Button'].iloc[2].grid(row=0, column=2, sticky=N+S+E+W, padx=5, pady=5)
# Quantity buttons
textQ = Label(frame_pad, text='Quantity', font=('Courrier', 25))
textQ.grid(row=0, column=0, columnspan=5, sticky=N+S+E+W, padx=5, pady=5)
btn_nb0 = Button(frame_pad, text=0, font=('Courrier', 25), command=lambda: set_quantity(0))
btn_nb0.grid(row=int(0/5)+1, column=0 % 5, sticky=N+S+E+W, padx=2, pady=5)
btn_nb1 = Button(frame_pad, text=1, font=('Courrier', 25), command=lambda: set_quantity(1))
btn_nb1.grid(row=int(1/5)+1, column=1 % 5, sticky=N+S+E+W, padx=2, pady=5)
btn_nb2 = Button(frame_pad, text=2, font=('Courrier', 25), command=lambda: set_quantity(2))
btn_nb2.grid(row=int(2/5)+1, column=2 % 5, sticky=N+S+E+W, padx=2, pady=5)
btn_nb3 = Button(frame_pad, text=3, font=('Courrier', 25), command=lambda: set_quantity(3))
btn_nb3.grid(row=int(3/5)+1, column=3 % 5, sticky=N+S+E+W, padx=2, pady=5)
btn_nb4 = Button(frame_pad, text=4, font=('Courrier', 25), command=lambda: set_quantity(4))
btn_nb4.grid(row=int(4/5)+1, column=4 % 5, sticky=N+S+E+W, padx=2, pady=5)
btn_nb5 = Button(frame_pad, text=5, font=('Courrier', 25), command=lambda: set_quantity(5))
btn_nb5.grid(row=int(5/5)+1, column=5 % 5, sticky=N+S+E+W, padx=2, pady=5)
btn_nb6 = Button(frame_pad, text=6, font=('Courrier', 25), command=lambda: set_quantity(6))
btn_nb6.grid(row=int(6/5)+1, column=6 % 5, sticky=N+S+E+W, padx=2, pady=5)
btn_nb7 = Button(frame_pad, text=7, font=('Courrier', 25), command=lambda: set_quantity(7))
btn_nb7.grid(row=int(7/5)+1, column=7 % 5, sticky=N+S+E+W, padx=2, pady=5)
btn_nb8 = Button(frame_pad, text=8, font=('Courrier', 25), command=lambda: set_quantity(8))
btn_nb8.grid(row=int(8/5)+1, column=8 % 5, sticky=N+S+E+W, padx=2, pady=5)
btn_nb9 = Button(frame_pad, text=9, font=('Courrier', 25), command=lambda: set_quantity(9))
btn_nb9.grid(row=int(9/5)+1, column=9 % 5, sticky=N+S+E+W, padx=2, pady=5)
# Action buttons
btn1 = Button(frame_action, text='In Stock', font=('Courrier', 25), command=lambda: set_action(btn1['text']))
btn1.grid(row=0, column=0, sticky=N+S+E+W, padx=5, pady=5)
btn2 = Button(frame_action, text='Ordered', font=('Courrier', 25), command=lambda: set_action(btn2['text']))
btn2.grid(row=0, column=1, sticky=N+S+E+W, padx=5, pady=5)
# Recall Labels, for the user to know what has been pressed
recall_product = Label(frame_recall, text=df_changes.iloc[0, 0], font=('Courrier', 15))
recall_product.pack()
recall_quantity = Label(frame_recall, text=df_changes.iloc[0, 1], font=('Courrier', 15))
recall_quantity.pack()
recall_action = Label(frame_recall, text=df_changes.iloc[0, 2], font=('Courrier', 15))
recall_action.pack()
# Make all the elements adjust correctly to resizing
for x in range(1):
Grid.columnconfigure(frame_pad, x, weight=1)
for y in range(3):
Grid.rowconfigure(frame_pad, y, weight=1)
for x in range(1):
Grid.columnconfigure(frame_action, x, weight=1)
for y in range(2):
Grid.rowconfigure(frame_action, y, weight=1)
Grid.columnconfigure(frame_recall, 0, weight=1)
for y in range(1):
Grid.rowconfigure(frame_recall, y, weight=1)
for x in range(4):
Grid.columnconfigure(frame, x, weight=1)
for y in range(4):
Grid.rowconfigure(frame, y, weight=1)
frame_pad.grid(row=0, column=3, sticky=N+S+E+W, padx=5, pady=5)
frame_action.grid(row=1, column=3, sticky=N+S+E+W, padx=5, pady=5)
frame_recall.grid(row=3, column=3, sticky=N+S+E+W, padx=5, pady=5)
# Display window
root.mainloop()
非常感謝您的幫助!
我運行了您的樣本,但不清楚您要做什么。 但我的建議是讓您 gui 僅從您的Dataframe
讀取和更新數據。 它可能是這樣的:
import pandas as pd
import tkinter as tk
from tkinter import ttk
df_product = pd.DataFrame({'Name': ['Juice', 'Cereal', 'Can'], 'In Stock': [0, 0, 0], 'Coming': [0, 0, 0], 'Button': [0, 0, 0]})
root = tk.Tk()
data = {}
def selection(txt, widget):
for v in data.values():
v[-1].config(relief="raised",bg="SystemButtonFace")
widget.config(relief="sunken",bg="red")
item.set(txt)
def set_amount():
result = data.get(item.get())
if result:
to_change = result[0] if inventory.get()=="In Stock" else result[1]
to_change.config(text=amount.get())
for row, x in enumerate(df_product.itertuples()):
button = tk.Button(root,text=x[1],width=10)
button.config(command=lambda b=button, x=x[1]: selection(x,b))
button.grid(row=row, column=0)
data[x[1]] = []
for col, txt in enumerate(x[2:-1],1):
label = tk.Label(root,text=txt,width=10)
label.grid(row=row, column=col)
data[x[1]].append(label)
data[x[1]].append(button)
tk.Label(root,text="Item selected:",width=10).grid(row=0,column=3)
item = tk.StringVar()
tk.Label(root,textvariable=item,width=10).grid(row=0,column=4)
inventory = ttk.Combobox(root,values=("In Stock","Coming"),state="readonly",width=10)
inventory.grid(row=1,column=3)
inventory.current(0)
amount = tk.Spinbox(root, from_=0, to=10, width=3,state="readonly")
amount.grid(row=1,column=4)
submit = tk.Button(root,text="Submit change",command=set_amount)
submit.grid(row=2,column=3,columnspan=2)
root.mainloop()
請注意,這沒有寫回Dataframe
的機制,但應該很容易實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.