Python/TKinter - 如何按名称生成所选小部件的列表

Python/TKinter - How to generate a list of selected widgets by name

为了清楚起见,我已经 re-written 这个问题。我对任何事情都持开放态度 - 如果需要,可以完全重新设计。

我遇到了一个问题,我试图从头开始,因为我找不到任何有效的解决方案。

我有一个包含 75 列的文件,每一列都是一个特征。我希望用户能够 select 在分析中包含哪些特征。

问题 1. 最好的小部件是什么? 首先,我尝试使用列表框,但它不会让我 select non-consecutive 项目,除非在默认状态下需要 selecting 每个单独的项目(有 75 个项目,所以这会点击很多)。

接下来,我尝试使用复选框。我 认为 这是最好的解决方案,但我在实施时遇到了问题。下面是 UI 的样子:

我试图将其与 'clicked' 框列表相关联,然后我可以将这些框传递给 back-end 以删除不需要的变量,因为应用程序的其余部分是数据密集型的。

select all 和 deselect all 按钮工作正常;我的问题是个人 selections.

这是实现这个目标的正确方法吗?如果是这样,这将如何实现? TIA- 我昨天开始使用 tkinter,所以我知道的很少。

下面是我如何生成(简化)

创建按钮的代码:

import tkinter as tk

settings.data_included_cols = ['button1'] #This is the list of clicked buttons

checkbox_buttons=dict()
checkbox_variables=dict()

button_names=['button1', 'button2', 'button3']

i=0

for i in range(len(button_names)):
    checkbox_variables[i]=1
    checkbox_button[i] = tk.Checkbutton(frame, text=button_names[i],
                                    variable=checkbox_variables[i],
                                    command=checkbox_click)

命令代码 (checkbox_click)- 我不知道这里发生了什么,但到目前为止我尝试过的都没有奏效。最初我称它为:command=lambda: checkbox_click(i),它试图像下面这样工作:

def checkbox_click(i):
    if i in settings.data_included_cols:
       settings.data_included_cols.remove(button_name[i])

这不起作用,因为 'i' 不与按钮相关联,它与循环相关联,因此它始终是最终值(在本例中为 3,映射到按钮 3)。

有什么想法吗?

问题在于,尽管您在创建它们时分配了每个 check-button 不同的“功能”,但是当单击其中一个按钮时,程序将执行该功能

lambda: feature_list(feature)

它将尝试获取“特征”的值,并发现它等于列表中的最后一个。

看似唯一的解决办法是给每个 check-button 分配一个变量,比如这样:

import tkinter as tk
from tkinter import ttk

def click():
    temp = []
    for i in range(3):
        if value[i].get() == 1:
            temp.append(feature[i])
    print(temp)

if __name__ == "__main__":

    root = tk.Tk()

    feature = ["one", "two", "three"]
    check = {}
    value = {}

    for i in range(3):
        value[i] = tk.IntVar(value=0)
        check[i] = ttk.Checkbutton(root, text=feature[i], variable=value[i], onvalue=1, offvalue=0, command=click)
        check[i].grid(row=0, column=i)

    root.mainloop()

然后当你select一些按钮,例如“一”和“三”时,它会打印

['one', 'three']

你不应该吝啬创建Tk变量,因为一个check-button消耗的space应该比一个变量消耗的大得多。此外,创建变量以获取小部件的状态是您应该始终使用的最“标准”和“Pythonic”方式。

复选框不需要指定命令。

它们 但是需要一个 StringVarIntVar 与它们相关联,以便您可以查询值。

所以我会像这样构建你的代码:

names = {
    "id", "member_id", "loan_amnt"
}

values = {}
boxes = {}

for name in names:
    values[name] = tk.Intvar(value=1)
    boxes = ttk.Checkbox(root, text=name, variable=values[name])

一旦用户提交了他们的选择,您可以查询 values 的字典以查看选择了哪些选项。