[英]Checkbutton does not work in tkinter python - Tkinter, checkbuttons, python
我使用 tkinter 作為接口來更新 dataframe。 我不想使用 treeview 因為我更喜歡使用網格。 如果您切換檢查按鈕,它會相應地更改其值(0 - 未選中,1 - 選中)為了獲得 df 的值,我使用與 df 中的 position 對應的每個檢查按鈕的變量 ex:var02 是df.iloc[0,2]
但是由於某種原因,按鈕column = AG
和rows = 11,21,31
不起作用,它們只有在我單獨創建它們時才起作用,而不是在 for 循環中。 我無法理解按鈕column = AG
和rows = 11,21,31
的問題是什么,以及為什么我在循環中創建它們時無法獲取值。
# update values in the df with saved variables
def update_vals():
for i in range(0,len(df.columns)):
for j in range(0,len(df.index)):
if pd.isna(df.iloc[j,i]) == False:
var = f"""df.iloc[j,i] = var{j}{i}.get()"""
exec(var)
#select all
def select_all():
for i in variables:
var=f"{i}.set(value=1)"
exec(var)
def deselect_all():
for i in variables:
var=f"{i}.set(value=0)"
exec(var)
#create test df
df = pd.DataFrame(np.random.randint(0,1,size=(33, 20)), columns=list('ABCDEFGHIGKLMPOPQRST'))
cols = df.columns
variables = []
#open window
top = Tk()
#create columns and index in the grid
for i in range(0,len(df.columns)):
tk.Label(top, text = df.columns[i]).grid(row = 0, column = i+1)
for i in range(0,len(df.index)):
tk.Label(top, text = i).grid(row = i+1, column = 0)
#create checkbuttons in the grid and assign values to checkbutton variables
for i in range(0,len(df.columns)):
for j in range(0,len(df.index)):
if pd.isna(df.iloc[j,i]) == False:
#var_str =f"global var{j}{i}"
#exec(var_str)
var_str=f"var{j}{i}=tk.IntVar(top)"
exec(var_str)
variables.append(f"var{j}{i}")
var_str=f"""Checkbutton(top, variable=var{j}{i}, onvalue = 1).grid(row = {j+1}, column = {i+1})"""
exec(var_str)
tk.Button(top, text="Update all", state=NORMAL, command=update_vals,bg="#C2CDD1").grid(column = 40, row = 32, sticky="ew")
tk.Button(top, text="Select all", state=NORMAL, command=select_all,bg="#C2CDD1").grid(column = 40, row = 5, sticky="ew")
tk.Button(top, text="Deselect all", state=NORMAL, command=deselect_all,bg="#C2CDD1").grid(column = 40, row = 6, sticky="ew")
top.mainloop()
錯誤來自某些變量名稱相同的事實。 在您的示例中: var112
可以是與第一行第 12 列關聯的變量,但它也是第 11 行第 2 列。
通常,像您這樣創建變量是非常糟糕的做法。 (也使用 exec 會使您的代碼不安全且更難調試)。 您應該將變量放在適當的結構中。 以 numpy 陣列為例:
import pandas as pd
import tkinter as tk
import numpy as np
# update values in the df with saved variables
def update_vals():
for i in range(0,len(df.columns)):
for j in range(0,len(df.index)):
if pd.isna(df.iloc[j,i]) == False:
df.iloc[j,i] = variables[j][i].get()
#select all
def select_all():
for row in variables:
for el in row:
el.set(value=1)
def deselect_all():
for row in variables:
for el in row:
el.set(value=0)
#create test df
df = pd.DataFrame(np.random.randint(0,1,size=(33, 20)), columns=list('ABCDEFGHIGKLMPOPQRST'))
cols = df.columns
#open window
top = tk.Tk()
variables = np.array([[tk.IntVar(top)]*len(df.columns)]*len(df.index))
#create columns and index in the grid
for i in range(0,len(df.columns)):
tk.Label(top, text = df.columns[i]).grid(row = 0, column = i+1)
for i in range(0,len(df.index)):
tk.Label(top, text = i).grid(row = i+1, column = 0)
#create checkbuttons in the grid and assign values to checkbutton variables
for i in range(0,len(df.columns)):
for j in range(0,len(df.index)):
if pd.isna(df.iloc[j,i]) == False:
tk.Checkbutton(top, variable=variables[j, i], onvalue = 1).grid(row = j+1, column = i+1)
tk.Button(top, text="Update all", state="normal", command=update_vals,bg="#C2CDD1").grid(column = 40, row = 32, sticky="ew")
tk.Button(top, text="Select all", state="normal", command=select_all,bg="#C2CDD1").grid(column = 40, row = 5, sticky="ew")
tk.Button(top, text="Deselect all", state="normal", command=deselect_all,bg="#C2CDD1").grid(column = 40, row = 6, sticky="ew")
top.mainloop()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.