Python Tkinter 中的单选按钮值

Posted

技术标签:

【中文标题】Python Tkinter 中的单选按钮值【英文标题】:Radio button values in Python Tkinter 【发布时间】:2016-06-10 04:15:52 【问题描述】:

我正在尝试使用 Tkinter 在 Python 中创建一个对话框。目标是有一个带有两个单选按钮和一个“确定”按钮的对话框。单选按钮一选择“默认”选项。单选按钮二选择“用户定义”选项。 “确定”按钮关闭窗口。

问题 1:如何保存单选按钮的值?也就是说,如何将选定的单选按钮传递给脚本的其余部分?

问题 2:如何让第二个单选按钮包含用户文本输入(沿着 tkSimpleDialog.askstring 行)?我希望该按钮显示一个单选按钮、一个提示(“输入值:”)和一个供用户输入文本的空间——所有这些都在一行上作为一个单选按钮选项。 所以整个对话框的顶部单选按钮应该是一个普通的单选按钮,而第二个按钮指定用户输入并包含该用户输入的空间(和 OK 按钮)。

到目前为止,我打开了一个包含两个选项的对话框,但该值没有传递给我可以看到的任何内容;即使在我选择单选按钮之前,选择也会返回为 0。 非常感谢您对这两个问题的任何帮助,谢谢。 到目前为止,这是我的脚本:

from Tkinter import*

master = Tk()
var = IntVar()
Label(master, text = "Select OCR language").grid(row=0, sticky=W)
Radiobutton(master, text = "default", variable = var, value = 1).grid(row=1, sticky=W)
Radiobutton(master, text = "user-defined", variable = var, value = 2).grid(row=2, sticky=W)
Button(master, text = "OK", command = master.quit).grid(row=3, sticky=W)
selection = var.get()
print "Selection:", selection
mainloop()
#If selection == 0 do one thing
#If selection == 1 do something else...

【问题讨论】:

"如果您需要在值更改时得到通知,请为每个按钮附加一个命令回调。"来自 effbot 文档effbot.org/tkinterbook/radiobutton.htm 另见tutorialspoint.com/python/tk_radiobutton.htm IntVar 默认值为 0,因此在您开始之前,mainloop var 的值为 0 yes。 hmm...不知道为什么它在master.quit() 之后又回到0,但在我的回答中它确实在end_program 中有正确的值。 【参考方案1】:

聚会有点晚了,但我在尝试在 Tkinter 单选按钮上查找内容时偶然发现了这个问题。

问题一:

我改变了三件事:

1) 在你定义之后,我立即将var 的值设置为1。这是通过var.set(1) 完成的,并确保您的第一个单选按钮被选中(其值为 1,正如您稍后在代码中定义的那样)。

2) 我已将您的master.quit 命令替换为一个名为quit_loop 的函数。在这个函数中:

var 值通过printget 语句打印。 get 将“获取”var 的当前值,这取决于选择了哪个单选按钮。 我在这个函数中创建了一个全局变量,然后将getvar 的当前值。 我在master.quit() 中添加了括号,因为这不再是单选按钮的命令。请注意,如果您打算使用 IDLE,master.destroy() 可能是 a more suitable alternative。

3) 由于在函数中创建了selection 变量,我们现在将您想要的值存储在变量中。代码末尾有一个最后的if-statement,表明它正在工作。

from Tkinter import *

master = Tk()
var = IntVar()
var.set(1)

def quit_loop():
    print "Selection:",var.get()
    global selection
    selection = var.get()
    master.quit()

Label(master, text = "Select OCR language").grid(row=0, sticky=W)
Radiobutton(master, text = "default", variable=var, value = 1).grid(row=1, sticky=W)
Radiobutton(master, text = "user-defined", variable=var, value = 2).grid(row=2, sticky=W)
Button(master, text = "OK", command=quit_loop).grid(row=3, sticky=W)

master.mainloop()

if selection == 1:
    print "My Value is equal to one."
elif selection == 2:
    print "My value is equal to two."

问题2:

我会保持简单,只需在您的单选按钮后添加一个标签和一个输入框。这意味着我们还必须处理列,因为您在之前的代码中没有定义任何列,这使得所有内容都默认为第 0 列。我们希望您的第二个单选按钮是“收音机、标签、条目”,它需要三列.

1) 先前包含"Select OCR language" 的标签将跨越三列,并将columnspan=3 添加到网格参数中。您的第一个单选按钮也是如此。

2) 我在您的第二个单选按钮之后添加了 LabelEntry。请注意,列从 0 到 2,定义了我们的三列。标签有一个简单的"Enter value:" 文本,而条目有变量textvariable=entry_text。我将此变量entry_text 添加到代码的开头,并立即将其值设置为###。请注意,这是一个 string(因此,文本变量),因此仅添加对整数的检查取决于您。

3) 当然,这与第二个单选按钮无关。如果我们选择它,它的值仍然是 2,而不是 Entry 小部件的值。这就是为什么在之前创建的quit_loop 函数中,我添加了一个小的if 语句,如果选择了第二个单选按钮,则该语句将条目的值分配给selection

from Tkinter import *

master = Tk()
var = IntVar()
var.set(1)

entry_text = StringVar()
entry_text.set("###")

def quit_loop():
    print "Selection:",var.get()
    global selection
    selection = var.get()

    if selection == 2:
        selection = entry_text.get()

    master.quit()

# Add columnspan to these widgets
Label(master, text = "Select OCR language").grid(row=0, sticky=W, columnspan=3)
Radiobutton(master, text = "default", variable=var, value = 1).grid(row=1, sticky=W, columnspan=3)

# Order these widgets in their appropriate columns
Radiobutton(master, variable=var, value = 2).grid(row=2, sticky=W, column=0)
Label(master, text="Enter value:").grid(row=2, sticky=W, column=1)
Entry(master, textvariable=entry_text).grid(row=2, sticky=W, column=2)

# Example of what happens without columnspan
Button(master, text = "OK", command=quit_loop).grid(row=3, sticky=W)

master.mainloop()

print selection

提示

如果这个简单的 GUI 仍然这么小,那么以这种方式编写代码是可以的。然而,在这方面进一步扩展我建议使用an object oriented approach,因为它确实提高了很多可读性,尤其是在定义函数时。这样就不必事先定义它们。

【讨论】:

【参考方案2】:

在窗口出现之前设置选择值(selection = 0)。

如果你想在 mainloop() 之后运行测试,selection = var.get() 也应该在 mainloop() 之后进行测试。

如果您不想在测试前关闭主窗口,请使用command=function

from Tkinter import *

def function():
    selection = var.get()

    if  selection == 1:
        # Default

    elif selection == 2:
        # User-defined

    else:#selection==0
        #No choice

    master.quit()

master = Tk()
var = IntVar()
Label(master, text = "Select OCR language").grid(row=0, sticky=W)
Radiobutton(master, text = "default", variable = var, value = 1).grid(row=1, sticky=W)
Radiobutton(master, text = "user-defined", variable = var, value = 2).grid(row=2, sticky=W)
Button(master, text = "OK", command = function).grid(row=3, sticky=W)
mainloop()

【讨论】:

【参考方案3】:

不要在 Button 的命令中直接使用 master.quit,而是定义一个完成程序然后调用 master.quit() 的函数:

def end_program(event=None):#event will let it be used as .bind callbacks too if you need it.
    selection = var.get()
    if selection:
        NotImplemented
    else:
        NotImplemented
    master.quit()

...

Button(master, text = "OK", command = end_program).grid(row=3, sticky=W)

master 已关闭,小部件中的一些数据已被清理,因此只有在您完成访问小部件后才需要调用 master.quit()

【讨论】:

以上是关于Python Tkinter 中的单选按钮值的主要内容,如果未能解决你的问题,请参考以下文章

Python3 Tkinter基础 LabelFrame Radiobutton 形成两组不相互限制的单选按钮

基于选定的单选按钮在 Tkinter 中启动命令?

tkinter 单选按钮未在类中显示值

如何在不单击tkinter python的情况下读取单选按钮值

为啥使用 StringVar 而不是 IntVar 时 Tkinter 的单选按钮都开始选中?

如何在 Python Tkinter 的按钮下方移动单选按钮的文本标签?