Изменить текст кнопки с помощью кнопки tkinter, хранящейся во фрейме данных Panda - PullRequest
0 голосов
/ 22 сентября 2019

Я недавно обнаружил Tkinter и хотел попробовать создать графический интерфейс, чтобы отслеживать запас некоторых предметов.

У меня есть таблица панды, содержащая информацию для каждого продукта: Имя, На складе (количество, доступное в настоящее время), Прибытие (количество в пути).У каждого продукта есть своя собственная кнопка, отображающая название продукта, количество на складе и текущее количество.

При нажатии на комбинацию продукт + количество + действие должна быть вызвана функция, которая обновит текст, отображаемый для каждой кнопки продукта. Моя проблема в том, что я не могу правильно получить доступ к тексту кнопки, чтобы обновить его. Чтобы иметь одну общую функцию для обновления текста кнопки для продукта, я сохранил кнопки во фрейме данных 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()

Большое спасибо за вашу помощь!

1 Ответ

0 голосов
/ 22 сентября 2019

Я проверил ваш образец, и совершенно неясно, что вы пытаетесь сделать.Но я предлагаю, чтобы вы только читали и обновляли данные с вашего 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, но оно должно быть достаточно простым для реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...