我正在使用clsGrpCheckButton类创建3组ttk.CheckButtons。 问题是我只能访问最后创建的组的状态,而不能访问上一组。
当点击任何组中的一个checkButtons时,我希望得到组中的检查按钮列表(通过使用方法chkGrpGetValue with是每个检查按钮的命令参数)
但是,无论单击哪个按钮,该方法只会返回最后一组的状态
以下是重新创建问题的代码,以及附件中显示问题的图片
求助于你。 RGDS
import tkinter as tk
from tkinter import ttk
import pandas as pd
class clsGrpCheckButton(ttk.Checkbutton):
def __init__(self,pContainer, pLstVal,pCommand,pInitValue=True):
self.grpChk=[0]*len(pLstVal)
self.grpKey=[0]*len(pLstVal)
self.grpLstVal = [0]*len(pLstVal)
self.grpVariable= [0]*len(pLstVal)
self.grpActiveKeys = [0]
for l,t in enumerate(pLstVal):
#l : index of the list of tuples
self.grpKey[l] = t[0]
self.grpLstVal[l] = t[1]
self.grpVariable[l] = tk.StringVar()
self.grpChk[l] = ttk.Checkbutton(pContainer, text=self.grpLstVal[l],
state='active' ,
onvalue= self.grpKey[l],
offvalue= '',
variable = self.grpVariable[l],
command=pCommand)
#get default value
if pInitValue :
self.grpVariable[l].set(self.grpKey[l])
self.grpActiveKeys.append(self.grpKey[l])
#get the index in the list of checkboxes
# depending on the key
def chkGrpGetIdx(self, pKey):
i=0
while i <len(self.grpKey):
if self.grpKey[i]==pKey :
return i
i=len(self.grpKey)
else:
i+=1
def chkGrpSetValue(self, pKey, pValue):
#need find correct index first
i=self.chkGrpGetIdx(pKey)
self.grpVariable[i] = pValue
#return the list of keys of the group
def chkGrpKeyLst(self):
return self.grpKey
#return the checkox element of the group of checkox
def chkGrpGetChkObj(self,pKey):
i=self.chkGrpGetIdx(pKey)
return self.grpChk[i]
#action when check/uncheck
#at list one element should be active
def chkGrpGetValue(self):
i=0
r=len(self.grpVariable)
self.grpActiveKeys.clear()
while i < len(self.grpVariable):
if self.grpVariable[i].get() =='':
r-=1
else:
self.grpActiveKeys.append(self.grpKey[i])
i+=1
if r==0:
self.grpVariable[0].set(self.grpKey[0])
self.grpActiveKeys.append(self.grpKey[0])
print(self.grpActiveKeys)
#to avoid accessing to class attribute directly
def chkGetCheckedValues(self):
return self.grpActiveKeys
class clsWindows(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
la = [1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3]
lb= [10,11,12,14,15,20,21,22,23,24,25,26,30,31,32,33]
lc=['d10','d11','d12','d14','d15','d20','d21','d22','d23','d24','d25','d26','d30','d31','d32','d33']
df = pd.DataFrame(
{'DIVISION': la,
'DEPT_CODE': lb,
'DEPT_NAME': lc
})
lW = list(zip(df['DIVISION'].astype(str) , df['DEPT_CODE'].astype(str)))
lpt = list(zip(df['DEPT_CODE'].astype(str) , df['DEPT_NAME'].astype(str)))
curHead = ""
r=0
c=-1
for head, DPT in lW:
if not curHead==head:
curHead = head
c+=1
r=0
dq=df.query('DIVISION=='+head)
lpt = list(zip(dq['DEPT_CODE'].astype(str) , dq['DEPT_NAME'].astype(str)))
t=ttk.Labelframe(self,text=head)
t.grid(column=c, row=0, sticky='nw')
self.checkGrpDept= clsGrpCheckButton(t,lpt,lambda:self.checkGrpDept.chkGrpGetValue(),True)
self.checkGrpDept.chkGrpGetChkObj(DPT).grid(column=c, row=r, sticky='nw')
t.rowconfigure(r, weight=1)
t.columnconfigure(c, weight=1)
r+=1
def wQuit(self):
self.destroy()
app = clsWindows()
app.mainloop()
答案 0 :(得分:1)
最后,我在为每个checkbutton分配命令时使用partial来提出解决方案。 如果某人遇到类似的问题,这是完整的代码
import tkinter as tk
from tkinter import ttk
import pandas as pd
from functools import partial
class clsGrpCheckButton():
def __init__(self,pContainer, pLstVal,pCommand,pInitValue=True):
self.grpChk=[0]*len(pLstVal)
self.grpKey=[0]*len(pLstVal)
self.grpLstVal = [0]*len(pLstVal)
self.grpVariable= [0]*len(pLstVal)
self.grpActiveKeys = [0]
for l,t in enumerate(pLstVal):
#l : index of the list of tuples
self.grpKey[l] = t[0]
self.grpLstVal[l] = t[1]
self.grpVariable[l] = tk.StringVar()
self.grpChk[l] = ttk.Checkbutton(pContainer, text=self.grpLstVal[l],
state='active' ,
onvalue= self.grpKey[l],
offvalue= '',
variable = self.grpVariable[l],
command=partial(pCommand,self))
#get default value
if pInitValue :
self.grpVariable[l].set(self.grpKey[l])
self.grpActiveKeys.append(self.grpKey[l])
#get the index in the list of checkboxes
# depending on the key
def chkGrpGetIdx(self, pKey):
i=0
while i <len(self.grpKey):
if self.grpKey[i]==pKey :
return i
i=len(self.grpKey)
else:
i+=1
def chkGrpSetValue(self, pKey, pValue):
#need find correct index first
i=self.chkGrpGetIdx(pKey)
self.grpVariable[i] = pValue
#return the list of keys of the group
def chkGrpKeyLst(self):
return self.grpKey
#return the checkox element of the group of checkox
def chkGrpGetChkObj(self,pKey):
i=self.chkGrpGetIdx(pKey)
return self.grpChk[i]
#action when check/uncheck
#at list one element should be active
def chkGrpGetValue(self):
i=0
r=len(self.grpVariable)
self.grpActiveKeys.clear()
while i < len(self.grpVariable):
if self.grpVariable[i].get() =='':
r-=1
else:
self.grpActiveKeys.append(self.grpKey[i])
i+=1
if r==0:
self.grpVariable[0].set(self.grpKey[0])
self.grpActiveKeys.append(self.grpKey[0])
print(self.grpActiveKeys)
#to avoid accessing to class attribute directly
def chkGetCheckedValues(self):
return self.grpActiveKeys
class clsWindows(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
la = [1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3]
lb= [10,11,12,14,15,20,21,22,23,24,25,26,30,31,32,33]
lc=['d10','d11','d12','d14','d15','d20','d21','d22','d23','d24','d25','d26','d30','d31','d32','d33']
df = pd.DataFrame(
{'DIVISION': la,
'DEPT_CODE': lb,
'DEPT_NAME': lc
})
lW = list(zip(df['DIVISION'].astype(str) , df['DEPT_CODE'].astype(str)))
lpt = list(zip(df['DEPT_CODE'].astype(str) , df['DEPT_NAME'].astype(str)))
curHead = ""
r=0
c=-1
for head, DPT in lW:
if not curHead==head:
curHead = head
c+=1
r=0
dq=df.query('DIVISION=='+head)
lpt = list(zip(dq['DEPT_CODE'].astype(str) , dq['DEPT_NAME'].astype(str)))
t=ttk.Labelframe(self,text=head)
t.grid(column=c, row=0, sticky='nw')
checkGrpDept= clsGrpCheckButton(t,lpt,clsGrpCheckButton.chkGrpGetValue,True)
checkGrpDept.chkGrpGetChkObj(DPT).grid(column=c, row=r, sticky='nw')
t.rowconfigure(r, weight=1)
t.columnconfigure(c, weight=1)
r+=1
def wQuit(self):
self.destroy()
app = clsWindows()
app.mainloop()