如何使用 Tkinter 和函数找到选择了哪个检查按钮?

Posted

技术标签:

【中文标题】如何使用 Tkinter 和函数找到选择了哪个检查按钮?【英文标题】:How can you find which checkbutton is selected using Tkinter and a function? 【发布时间】:2021-07-01 23:02:53 【问题描述】:

这里我试图创建一个包含三种水果的列表,苹果、石榴和香蕉,并要求用户选择他们最喜欢的水果。因此,我在每次选择任何复选框时定义调用的函数print_choice,并且已定义一个阵列果实,该阵列果实将相应的水果附加到数组时选择复选框。 我在函数内部定义了数组,而不是全局声明,因为不应将值添加两次。但是,我无法将选择打印在应该显示用户选择的水果列表的标签框中。能否请您帮我找出我在哪里出错以及如何显示选择的水果?

 import tkinter as tk
from tkinter import *

parent = tk.Tk()
parent.title("My favorite fruits")
l= tk.Label(parent, background="yellow", text="empty", )
l.pack()
w = tk.Label(parent , text ="Select your favorite fruits!", bg="pink", fg = "white")

txt = "you love "
def print_choice():
    fruits=list()
    global txt
    flag=0
    while flag==0:
         if checkvar1.get()==1 and checkvar2.get==0 and checkvar3.get()==0:
             fruits.append("Apple")
             flag=1
             break
         elif checkvar2.get()==1 and checkvar1.get()==0 and checkvar3.get()==0:
             fruits.append("Pomegranate")
             flag=1
             break
         elif checkvar3.get()==1 and checkvar1.get()==0 and checkvar2.get()==0:
             fruits.append("Banana")
             flag=1
             break
         elif checkvar3.get()==1 and checkvar1.get()==1 and checkvar2.get()==0:
             fruits.append("Banana")
             fruits.append("Apple")
             flag=1
             break
         elif checkvar3.get()==1 and checkvar1.get()==0 and checkvar2.get()==1:
             fruits.append("Banana")
             fruits.append("Pomegranate")
             flag=1
             break
         elif checkvar3.get()==0 and checkvar1.get()==1 and checkvar2.get()==1:
             fruits.append("Apple")
             fruits.append("Pomegranate")
             flag=1
             break
         elif checkvar3.get()==1 and checkvar1.get()==1 and checkvar2.get()==1:
             fruits.append("Banana")
             fruits.append("Apple")
             fruits.append("Pomegranate")
             flag=1
             break
         else :
             fruits.append(" ")

         for fruit in fruits:
             txt += fruit+" "
         l.config(text=txt)
    
   
    
    
    
    
    
checkvar1= tk.IntVar()
checkvar2 = tk.IntVar()
checkvar3 = tk.IntVar()


c1 = tk.Checkbutton(parent, text ="Apple", variable = checkvar1, onvalue=1, offvalue=0,height = 5, width =20, bg="pink", activebackground="yellow", activeforeground="orange", command=print_choice)
c1.pack()
c2 = tk.Checkbutton(parent, text ="Pomegranate", variable = checkvar2, onvalue=1, offvalue=0,height = 5, width =20, bg="pink", command=print_choice)
c2.pack()
c3 = tk.Checkbutton(parent, text ="Banana", variable = checkvar3, onvalue=1, offvalue=0,height = 5, width =20, bg="pink", command=print_choice)
c3.pack()





parent.mainloop()

这是我得到的输出:

每当我尝试选择一个复选框时,Python 都会停止响应。有没有可能我在某个地方遇到了无限循环?

【问题讨论】:

我要说的第一件事,肯定有比使用大量 if elif else 语句更好的方法(会给你一个例子) 【参考方案1】:

以下是您可能希望如何执行此操作的示例:

from tkinter import Tk, Checkbutton, IntVar


root = Tk()

selected = []


class Choice:
    def __init__(self, text):
        self.text = text
        self.state = IntVar()

        self.checkbutton = Checkbutton(root, text=self.text, command=self.check,
                                       variable=self.state, onvalue=1, offvalue=0)
        self.checkbutton.pack()

    def check(self):
        state = self.state.get()
        if state == 1:
            selected.append(self.text)
        if state == 0:
            selected.remove(self.text)
        print(selected)


c1 = Choice('Apple')
c2 = Choice('Orange')
c3 = Choice('Pear')

root.mainloop()

在这种情况下,您可以根据需要添加任意数量的复选框,并且您在硬编码代码中唯一要做的就是像 var_name = Choice('checkbutton name') 那样启动 Choice 类,其中 var_name 是您想要的任何变量名称,并且检查按钮名称是您想要的任何名称(只是为了澄清)。

【讨论】:

哦,是的!我现在明白了!非常感谢!【参考方案2】:

你不需要很多 if-else 语句就能知道用户喜欢哪种水果。

我将向您展示实现同一目标的另外两种方法。

第一种方法是创建一个字典,其中水果名称作为键,控制变量作为值。 现在遍历项目,检查控制变量的值是否为 1。如果为 1,则追加到水果列表。

第一种方式(使用字典):

import tkinter as tk

parent = tk.Tk()
parent.title("My favorite fruits")
l= tk.Label(parent, background="yellow", text="empty", )
l.pack()
w = tk.Label(parent , text ="Select your favorite fruits!", bg="pink", fg = "white")

txt = "you love "
def print_choice():
    global fruit_lst

    for fruit, checked in fruits_dict.items():

        if checked.get() and fruit not in fruit_lst:
            print(fruit)
            fruit_lst.append(fruit)

        if fruit in fruit_lst and not checked.get():
            fruit_lst.remove(fruit)
    
    l.config(text=txt+' ,'.join(fruit_lst))
    

checkvar1= tk.IntVar()
checkvar2 = tk.IntVar()
checkvar3 = tk.IntVar()

fruits_dict = "Apple": checkvar1, "Pomegranate": checkvar2, "Banana": checkvar3

fruit_lst = []

c1 = tk.Checkbutton(parent, text ="Apple", variable = checkvar1, onvalue=1, offvalue=0,height = 5, width =20, bg="pink", activebackground="yellow", activeforeground="orange", command=print_choice)
c1.pack()
c2 = tk.Checkbutton(parent, text ="Pomegranate", variable = checkvar2, onvalue=1, offvalue=0,height = 5, width =20, bg="pink", command=print_choice)
c2.pack()
c3 = tk.Checkbutton(parent, text ="Banana", variable = checkvar3, onvalue=1, offvalue=0,height = 5, width =20, bg="pink", command=print_choice)
c3.pack()


parent.mainloop()

您可以使用以下代码避免字典和循环:

import tkinter as tk

parent = tk.Tk()
parent.title("My favorite fruits")
l= tk.Label(parent, background="yellow", text="empty", )
l.pack()
w = tk.Label(parent , text ="Select your favorite fruits!", bg="pink", fg = "white")

txt = "you love "

def current(x, var):
    global fruit_lst

    if var.get():
        fruit_lst.append(x['text'])

    else:
        try:
            fruit_lst.remove(x['text'])
        except ValueError:
            pass
        
    print(fruit_lst)


checkvar1= tk.IntVar()
checkvar2 = tk.IntVar()
checkvar3 = tk.IntVar()


fruit_lst = []

c1 = tk.Checkbutton(parent, text ="Apple", variable = checkvar1, onvalue=1, offvalue=0)
c1.config(command = lambda x=c1, var=checkvar1: current(x, var))
c1.pack()

c2 = tk.Checkbutton(parent, text ="Pomegranate", variable = checkvar2, onvalue=1, offvalue=0)
c2.config(command = lambda x=c2, var=checkvar2: current(x, var))
c2.pack()

c3 = tk.Checkbutton(parent, text ="Banana", variable = checkvar3, onvalue=1, offvalue=0)
c3.config(command = lambda x=c3, var=checkvar3: current(x, var))
c3.pack()

parent.mainloop()

【讨论】:

是的,是的,非常感谢您提供的替代方案!我明白了,会尝试他们两个

以上是关于如何使用 Tkinter 和函数找到选择了哪个检查按钮?的主要内容,如果未能解决你的问题,请参考以下文章

tkinter(多个Button对应同一个回调函数如何识别响应的是哪个Button?)

如何在 Tkinter 中选择颜色?

带有 tkinter gui 的彩票号码生成器和检查器

使用 python tkinter 在单独的窗口中显示 pdf

具有或不具有对象继承的 tkinter GUI

在 Python 3 和 tkinter 中使用变量调用函数