代码之家  ›  专栏  ›  技术社区  ›  Tony

复选按钮和条目之间的通信(框)

  •  0
  • Tony  · 技术社区  · 6 年前
    从tkinter导入* 将熊猫作为PD导入 df=pd.dataframe(“item”:list(“abcde”),“默认值”:[2,6,4,5,1]) def输入数据(df): Box=tk() 高度=str(int(25*(df.形状[0]+2))) Box.Geometry(“320x”+高度) 框标题(“我的框”) #初始化 参数,复选按钮,intvars=[],[],[] 默认值=列表(df.default值) item list=列表(df.item) 对于i,枚举(项列表)中的标签: label(box,text=label).grid(row=i,sticky=w) params.append(条目(框)) 参数[-1]。网格(行=i,列=1) 参数[-1]。插入(i,默认值[i]) intvars.append(intvar()) checkbuttons.append(checkbutton(variable=intvars[-1])) checkbuttons[-1].网格(row=i,column=3) def sumbit(事件=无): 全局字段,选中 fields=[params[i].get()for i in range(len(params))] checked=[intvars[i].get()for i in range(len(intvars))] 销毁() #添加提交按钮 box.bind('<return>',sumbit) 按钮(box,text=“Submit”, command=sumbit).grid(row=df.shape[0]+3,sticky=w) 聚焦力()) 主环() 返回字段,选中 < /代码>

    我是个新手,不知道我想做什么是可能的。

    目前,我的脚本(这里简化为一个函数,而不是一个类)构建了一个框,其中包含在字段中输入的所有默认值:

    相反,我想从空字段开始,单击相应的复选按钮将获得默认值(现在仍然可以通过字段手动更改它),并且,一旦在给定字段中输入任何值,将选择相应的复选按钮。

    这些是可能的吗?

    我是个新手,不知道我想做什么是可能的。

    目前,我的脚本(这里简化为一个函数而不是一个类)构建了一个框,其中所有默认值都输入到字段中:

    enter image description here

    相反,我想从空字段开始,单击相应的复选按钮将获得默认值(现在仍然可以通过字段手动更改它),并且,一旦在给定字段中输入任何值,将选择相应的复选按钮。

    这些是可能的吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   r.ook jpp    6 年前

    1. from tkinter import *

      import tkinter as tk
      
      tk.Label() # same as if you wrote Label()
      tk.IntVar() # same as if you called IntVar()
      

    trace StringVar() Entry

    # add strVars as a list of StringVar() for your Entry box
    params, checkButtons, intVars, strVars = [], [], [], []
    

    enumerate(itemList)

    # Create new StringVar()
    strVars.append(StringVar())
    
    # add a trace callback for tracking changes over the StringVar()
    strVars[-1].trace_add('write', lambda var, var_idx, oper, idx=i: trace_strVar(idx))
    
    # update your Entry to set textvariable to the new strVar
    params.append(Entry(box, textvariable=strVars[-1]))
    
    
    # similarly, add a trace for your IntVar
    intVars[-1].trace_add('write', lambda var, var_idx, oper, idx=i: trace_intVar(idx))
    

    def trace_intVar(idx):
    
        # if Checkbox is checked and Entry is empty...     
        if intVars[idx].get() and not params[idx].get():
    
            # prefill Entry with default value
            params[idx].insert(0, df.default_vals[idx])
    
    def trace_strVar(idx):
    
        # if Entry has something...
        if strVars[idx].get():
    
            # and Checkbox is not checked...
            if not intVars[idx].get():
    
                # Set the checkbox to checked.
                intVars[idx].set(True)
    
        # but if Entry is empty...
        else:
    
            # Set the Checkbox to uncheck.
            intVars[idx].set(False)
    

    Checkbox

    trace_add (see this great answer from Bryan Oakley) lists lambda

    lambda var,        # reserve first pos for variable name
           var_idx,    # reserve second pos for variable index
           oper,       # reserve third pos for operation
           idx=i:      # pass in i by reference for indexing point
    trace_intVar(idx)  # only pass in the idx
    

    lambda...: trace_intVar(i) i idx

    trace('w', ...)


    from tkinter import *
    import pandas as pd
    
    df = pd.DataFrame({'item': list('abcde'), 'default_vals': [2,6,4,5,1]})
    
    def input_data(df):
        box = Tk()
        height = str(int(25*(df.shape[0]+2)))
        box.geometry("320x" + height)
        box.title("my box")
    
        #initialise
        params, checkButtons, intVars, strVars = [], [], [], []
        default_vals = list(df.default_vals)
        itemList = list(df.item)
    
        def trace_intVar(idx):        
            if intVars[idx].get() and not params[idx].get():
                params[idx].insert(0, df.default_vals[idx])
    
        def trace_strVar(idx):
            if strVars[idx].get():
                if not intVars[idx].get():
                    intVars[idx].set(True)
            else:
                intVars[idx].set(False)
    
    
        for i,label in enumerate(itemList):
            Label(box, text = label).grid(row = i, sticky = W)
            strVars.append(StringVar())
            strVars[-1].trace_add('write', lambda var, var_idx, oper, idx=i: trace_strVar(idx))
            params.append(Entry(box, textvariable=strVars[-1]))
            params[-1].grid(row = i, column = 1)
            #params[-1].insert(i, default_vals[i])  # <-- You don't need this any more
            intVars.append(IntVar())
            intVars[-1].trace_add('write', lambda var, var_idx, oper, idx=i: trace_intVar(idx))
            checkButtons.append(Checkbutton(variable = intVars[-1]))
            checkButtons[-1].grid(row = i, column = 3)
    
    
    
        def sumbit(event=None):  
            global fields, checked
            fields = [params[i].get() for i in range(len(params))]
            checked = [intVars[i].get() for i in range(len(intVars))]
            box.destroy()
    
        #add submit button
        box.bind('<Return>', sumbit) 
        Button(box, text = "submit",
               command = sumbit).grid(row = df.shape[0]+3, sticky = W)                                          
        box.focus_force() 
        mainloop()        
    
        return fields, checked