【问题标题】:How to get the text of Checkbuttons?如何获取 Checkbuttons 的文本?
【发布时间】:2018-07-04 07:59:40
【问题描述】:

Checkbuttons 是动态生成的,它们从 python 列表中获取文本。 我需要一个逻辑来捕获选定的检查按钮文本。 根据我在各地的研究,他们正在返回复选框而不是文本的状态。 请帮忙。

cb_list =['pencil','pen','book','bag','watch','glasses','passport','clothes','shoes','cap'] 
try:
    r = 0
    cl = 1
    for op in cb_list:
        cb = Checkbutton(checkbutton_frame, text=op, relief=RIDGE)
        cb.grid(row=r, column=cl, sticky="W")
        r = r + 1
except Exception as e:
    logging.basicConfig(filename=LOG_FILENAME, level=logging.ERROR)
    logging.error(e)
    # print (e)
 selected_item = Text(self, width=30, height=20, wrap=WORD)
 selected_item.grid(row=1, column=6, padx=20, pady=20, columnspan=2, sticky=E)

 display_button = Button(self, text='DISPLAY', command=display()
 convert_button.grid(row=1, column=8, padx=20, pady=20)

【问题讨论】:

  • 请提供minimal reproducible example。您谈论条目,但在上面甚至没有Entry
  • @Nae 这个编辑解释好吗?
  • 我不这么认为。事实证明,您希望您的文本改为 Text?它仍然不是minimal reproducible example。请转到链接并阅读。
  • 您还需要在文本中指定它们的顺序是否重要。
  • 我认为使用Listbox 比使用Text 小部件更容易。

标签: python tkinter tkinter-entry


【解决方案1】:

不要覆盖相同的变量cb,而是尝试使用dictionary 等可迭代类型。您还需要将Checkbutton 的值附加到tkinter variable class,例如BooleanVar,以便轻松跟踪其状态和值。


下面的代码生成一个 GUI,每次选择 Checkbutton 时都会重写 Text。它首先填充字典cbs,其中列表中的项目cb_list 作为键,tk.Checkbutton 对象作为值。

Checkbutton 对象是这样的,每个对象都附加到一个特殊的对象,Tkinter 变量类,BooleanVar,它有一个 get 方法返回 Checkbutton 它在调用时附加到的当前值。在这种情况下,每个Checkbutton 如果选中则保存True,如果未选中则保存False 作为其值。

每个Checkbutton 还附加到一个方法update_text,当任何Checkbutton 被按下时都会调用该方法。在该方法中,对于cbs 中的每个Checkbutton,它首先检查Checkbutton 是否具有True 值,如果是,则将其text 附加到_string。在对所有Checkbuttons 完成此操作后,该方法首先将delete 处理Text 小部件中的整个文本,然后将_string 放入Text

代码:

import tkinter as tk


def update_text():
    global cbs
    _string = ''
    for name, checkbutton in cbs.items():
        if checkbutton.var.get():
            _string += checkbutton['text'] + '\n'
    text.delete('1.0', 'end')
    text.insert('1.0', _string)


if __name__ == '__main__':
    root = tk.Tk()
    text = tk.Text(root)

    cb_list =['pencil','pen','book','bag','watch','glasses','passport',
                                                'clothes','shoes','cap']
    cbs = dict()
    for i, value in enumerate(cb_list):
        cbs[value] = tk.Checkbutton(root, text=value, onvalue=True,
                                offvalue=False, command=update_text)
        cbs[value].var = tk.BooleanVar(root, value=False)
        cbs[value]['variable'] = cbs[value].var

        cbs[value].grid(row=i, column=0)

    text.grid()
    root.mainloop()

textCheckbutton 小部件的一个选项,这意味着您可以使用cget(widget.cget('option')) 或简单地使用widget['option'] 来获取它的值。

【讨论】:

  • 你的回答也给了我及时的输出@Nae谢谢
【解决方案2】:

这个想法是将一个BooleanVar 关联到每个复选按钮,并将它们存储在一个列表cb_var 中。然后,要显示选中的项目,我们只需要清除显示框(我使用了Listbox),然后同时循环通过cb_listcb_var 来确定哪些项目被选中:

import tkinter as tk

root = tk.Tk()
checkbutton_frame = tk.Frame(root)
checkbutton_frame.grid(row=1, column=0)

def display():
    # clear listbox
    selected_item.delete(0, 'end')
    # add selected items in listbox
    for text, var in zip(cb_list, cb_var):
        if var.get():
            # the checkbutton is selected
            selected_item.insert('end', text)

cb_list = ['pencil','pen','book','bag','watch','glasses','passport','clothes','shoes','cap'] 
cb_var = []  # to store the variables associated to the checkbuttons
cl = 1
for r, op in enumerate(cb_list):
    var = tk.BooleanVar(root, False)
    cb = tk.Checkbutton(checkbutton_frame, variable=var, text=op, relief='ridge')
    cb.grid(row=r, column=cl, sticky="w")
    cb_var.append(var)

selected_item = tk.Listbox(root, width=30, height=20)
selected_item.grid(row=1, column=6, padx=20, pady=20, columnspan=2, sticky='e')

display_button = tk.Button(root, text='DISPLAY', command=display)
display_button.grid(row=1, column=8, padx=20, pady=20)

root.mainloop()

编辑:如果您希望能够轻松更改项目列表,可以使用函数init_checkbuttons 从列表中创建复选按钮 的项目。这个函数做了以下事情:

  1. 销毁所有以前的检查按钮
  2. 清除列表框
  3. 创建新的复选按钮
  4. 更改显示按钮的命令

您会注意到display 函数现在将cb_listcb_var 作为参数,因此您可以更改它们。

import tkinter as tk

root = tk.Tk()
checkbutton_frame = tk.Frame(root)
checkbutton_frame.grid(row=1, column=0)

def display(cb_list, cb_var):
    # clear listbox
    selected_item.delete(0, 'end')
    # add selected items in listbox
    for text, var in zip(cb_list, cb_var):
        if var.get():
            # the checkbutton is selected
            selected_item.insert('end', text)

def init_checkbuttons(cb_list, cl=1):
    # destroy previous checkbuttons (assuming that checkbutton_frame only contains the checkbuttons)
    cbs = list(checkbutton_frame.children.values())
    for cb in cbs:
        cb.destroy()
    # clear listbox
    selected_item.delete(0, 'end')
    # create new checkbuttons
    cb_var = []  # to store the variables associated to the checkbuttons
    for r, op in enumerate(cb_list):
        var = tk.BooleanVar(root, False)
        cb = tk.Checkbutton(checkbutton_frame, variable=var, text=op, relief='ridge')
        cb.grid(row=r, column=cl, sticky="w")
        cb_var.append(var)
    # change display command
    display_button.configure(command=lambda: display(cb_list, cb_var))

cb_list = ['pencil', 'pen', 'book', 'bag', 'watch', 'glasses', 'passport', 'clothes', 'shoes', 'cap']
cb_list2 = ['ball', 'table', 'bat']

selected_item = tk.Listbox(root, width=30, height=20)
selected_item.grid(row=1, column=6, padx=20, pady=20, columnspan=2, sticky='e')

display_button = tk.Button(root, text='DISPLAY')
display_button.grid(row=1, column=8, padx=20, pady=20)

tk.Button(root, text='Change list', command=lambda: init_checkbuttons(cb_list2)).grid(row=2, column=8)

init_checkbuttons(cb_list)
root.mainloop()

【讨论】:

  • 如何清除勾选按钮?现在列表是这样的: cb_list = ['pencil','pen','book','bag','watch','glasses','passport','clothes','shoes','cap'] 但是如果列表在第二次迭代中发生变化 cb_list = ['ball','table','bat'] 所以我想清除以前的检查按钮以获取我尝试使用 checkbutton.destroy() 的新检查按钮,但它会破坏并且不会创建新的检查按钮
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-10
  • 2018-06-13
  • 2022-01-03
  • 2021-12-18
相关资源
最近更新 更多