无法获取组的变量值ttk.复选按钮

2024-09-28 23:30:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在创建3组ttk.复选按钮,使用类clsGrpCheckButton。 问题是我只能访问上一个创建的组的状态,而不能访问上一个组的状态。你知道吗

当单击任何组的某个checkbutton时,我希望得到该组中checkButtons check的列表(使用chkGrpGetValue方法是每个checkbutton的命令参数)

但是,无论单击哪个按钮,该方法都只返回最后一个组的状态

下面是重新创建问题的代码,并在附件中显示了问题的图片

谢谢你的帮助。 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()

Example of issue


Tags: oftheselfdflenreturndeflist
1条回答
网友
1楼 · 发布于 2024-09-28 23:30:05

最后,我提出了一个解决方案,在将命令分配给每个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()

相关问题 更多 >