簡體   English   中英

使用 tkinter 更改按鈕的文本,並將按鈕存儲在熊貓數據框中

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM