【问题标题】:Tkinter: Multiple Radio ButtonsTkinter:多个单选按钮
【发布时间】:2020-11-29 11:41:41
【问题描述】:

我正在创建一个多项选择测试,一个问题将包含 3 个部分(下面仅显示 2 个 - 完成后将添加第 3 个)。

我希望用户回答所有部分,然后点击提交按钮记录答案。

我在课堂上有提示/选择。

我显示选项和单选按钮,一切正常。当所有部分都没有回答时,它会发出警告。但是我的方法很愚蠢。我目前显示一条消息,然后在做出所有选择并再次单击按钮时简单地用空白覆盖它。我不能.destroy.remove 因为如果我的条件不是我的意思,则创建了子标签并且我得到了一个错误。我可能应该将显示器放在计时器上,然后将其移除。

理想情况下,在做出所有选择之前,我的提交按钮将被禁用,但我还没有弄清楚。

那么您能帮我处理警告消息还是禁用提交按钮,直到所有单选按钮组都有选择?

# First Group of Radio buttons
Radiobutton(manuframe, text=manu_questions.prompt1, padx=xpad, pady=ypad, bg=background,
            fg=text_color, font=(text_type, text_height), variable=man_answer,
            value=1).pack(anchor=W)
Radiobutton(manuframe, text=manu_questions.prompt2, padx=xpad, pady=ypad, bg=background,
            fg=text_color, font=(text_type, text_height), variable=man_answer,
            value=2).pack(anchor=W)
Radiobutton(manuframe, text=manu_questions.prompt3, padx=xpad, pady=ypad, bg=background,
            fg=text_color, font=(text_type, text_height), variable=man_answer,
            value=3).pack(anchor=W)
Radiobutton(manuframe, text=manu_questions.prompt4, padx=xpad, pady=ypad, bg=background,
            fg=text_color, font=(text_type, text_height), variable=man_answer,
            value=4).pack(anchor=W)

#Second Group of Radio Buttons
Radiobutton(modelframe, text=model_questions.prompt1, padx=xpad, pady=ypad, bg=background,
            fg=text_color, font=(text_type, text_height), variable=mod_answer,
            value=1).pack(anchor=W)
Radiobutton(modelframe, text=model_questions.prompt2, padx=xpad, pady=ypad, bg=background,
            fg=text_color, font=(text_type, text_height), variable=mod_answer,
            value=2).pack(anchor=W)
Radiobutton(modelframe, text=model_questions.prompt3, padx=xpad, pady=ypad, bg=background,
            fg=text_color, font=(text_type, text_height), variable=mod_answer,
            value=3).pack(anchor=W)
Radiobutton(modelframe, text=model_questions.prompt4, padx=xpad, pady=ypad, bg=background,
            fg=text_color, font=(text_type, text_height), variable=mod_answer,
            value=4).pack(anchor=W)

#Submit Button
submitButton = Button(btm_frame2, text="Submit", command=lambda:submit(q, question_count,
                      mod_answer, man_answer))
submitButton.pack()

#Submission function - Check all questions answered, if so increment question.
# index and continue.
def submit(q, question_count, mod_answer, man_answer):

    if mod_answer.get() == 0 or man_answer.get() == 0:
        warn_label =Label(btm_frame2, text="You didn't answer", bg="red", fg="white")
        warn_label.place(relx=.5, y=10, anchor=CENTER)
    else:
        replace_label = Label(btm_frame2,
                              text="                                            ",
                              bg="green", fg="white")
        replace_label.place(relx=.5, y=10, anchor=CENTER)
        if q == question_count:
            raise SystemExit(0)
        else:
            q = q + 1

【问题讨论】:

  • 我建议使用tlinter.messagebox 对话框之一在用户单击提交时通知他们没有回答所有部分。这里有一些info 可用的种类。另请注意,您应该准确提及您在问题中遇到的错误或警告。
  • @martineau 你的意思是tkinter.messagebox?
  • 是的,我的意思是tkinter.messagebox。无论如何,如果您edit 您的问题并提供可运行的minimal reproducible example,人们可以向您展示如何实现您想要的。

标签: python tkinter radio-button


【解决方案1】:

这是一个基于您的代码的示例——有足够的脚手架可以实际运行——它说明了在没有做出所有选择时如何简单地显示一个内置的tlinter.messageboxdialogs

以这种方式做事的一个优点是它不需要销毁、删除或清除内容,因为当用户单击 OK 按钮确认消息时会自动发生这种情况。

from tkinter import *
from tkinter.messagebox import showerror


class Questions:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)


manu_questions = Questions(
                    prompt1='manu prompt1',
                    prompt2='manu prompt2',
                    prompt3='manu prompt3',
                    prompt4='manu prompt4'
                 )

model_questions = Questions(
                    prompt1='model prompt1',
                    prompt2='model prompt2',
                    prompt3='model prompt3',
                    prompt4='model prompt4'
                  )

BACKGROUND = 'white'
TEXT_COLOR, TEXT_TYPE, TEXT_HEIGHT = 'black', 'arial.ttf', 12
XPAD, YPAD = 2, 2


root = Tk()

# First Group of Radio buttons
manuframe = Frame(root,  borderwidth=1, padx=4, pady=4)
manuframe.pack()
man_answer = IntVar(value=0)

Radiobutton(manuframe, text=manu_questions.prompt1, padx=XPAD, pady=YPAD, bg=BACKGROUND,
            fg=TEXT_COLOR, font=(TEXT_TYPE, TEXT_HEIGHT), variable=man_answer,
            value=1).pack(anchor=W)
Radiobutton(manuframe, text=manu_questions.prompt2, padx=XPAD, pady=YPAD, bg=BACKGROUND,
            fg=TEXT_COLOR, font=(TEXT_TYPE, TEXT_HEIGHT), variable=man_answer,
            value=2).pack(anchor=W)
Radiobutton(manuframe, text=manu_questions.prompt3, padx=XPAD, pady=YPAD, bg=BACKGROUND,
            fg=TEXT_COLOR, font=(TEXT_TYPE, TEXT_HEIGHT), variable=man_answer,
            value=3).pack(anchor=W)
Radiobutton(manuframe, text=manu_questions.prompt4, padx=XPAD, pady=YPAD, bg=BACKGROUND,
            fg=TEXT_COLOR, font=(TEXT_TYPE, TEXT_HEIGHT), variable=man_answer,
            value=4).pack(anchor=W)

# Second Group of Radio Buttons
modelframe = Frame(root,  borderwidth=1, padx=4, pady=4)
modelframe.pack()
mod_answer = IntVar(value=0)

Radiobutton(modelframe, text=model_questions.prompt1, padx=XPAD, pady=YPAD, bg=BACKGROUND,
            fg=TEXT_COLOR, font=(TEXT_TYPE, TEXT_HEIGHT), variable=mod_answer,
            value=1).pack(anchor=W)
Radiobutton(modelframe, text=model_questions.prompt2, padx=XPAD, pady=YPAD, bg=BACKGROUND,
            fg=TEXT_COLOR, font=(TEXT_TYPE, TEXT_HEIGHT), variable=mod_answer,
            value=2).pack(anchor=W)
Radiobutton(modelframe, text=model_questions.prompt3, padx=XPAD, pady=YPAD, bg=BACKGROUND,
            fg=TEXT_COLOR, font=(TEXT_TYPE, TEXT_HEIGHT), variable=mod_answer,
            value=3).pack(anchor=W)
Radiobutton(modelframe, text=model_questions.prompt4, padx=XPAD, pady=YPAD, bg=BACKGROUND,
            fg=TEXT_COLOR, font=(TEXT_TYPE, TEXT_HEIGHT), variable=mod_answer,
            value=4).pack(anchor=W)


# Submit Button
submitButton = Button(root, text="Submit",
                      command=lambda: submit(man_answer, mod_answer))
submitButton.pack()

def submit(*variables):
    """ Check all questions answered. """
    question_not_answered = any(not v.get() for v in variables)
    if question_not_answered:
        showerror('Screw Up!', f"Answer all {len(variables)} parts before submission")
    else:
        ... # Whatever you want to happen when they are all answered.


root.mainloop()

点击按钮后显示错误对话框的屏幕截图:


为了快速参考,下面是所有其他 tkinter.messagebox 对话框的样例:

【讨论】:

  • 谢谢。我不知道我是否喜欢警告框。但这绝对是一个可行的解决方案,所以谢谢。
  • 约翰:是的……我想是口味问题。顺便说一句,在这里表示感谢的方式是对答案进行投票,此外,您可以“接受”您最喜欢的答案 - 请参阅How does accepting an answer work?
【解决方案2】:

我认为解决此问题的最佳方法是禁用 'Submit' 按钮,直到两个无线电输入(如您所说的将来为 3)都未填充。

通过一些研究,我找到了Disable/Enable buttons 的方法以及Radio button events 的另一个帖子

基本上,您应该有 3 个布尔变量(对于每组单选按钮),将它们全部设置为 False,当您单击其中一个按钮时,您调用一个将变量设置为 @987654325 的函数@(如果还没有的话),并检查所有变量是否已经是True,这样就可以启用按钮了。

您可能希望将这些变量放入global,以便更改值。

【讨论】:

  • 所以我基本上是这样做的。我将在 Radiobutton 中使用的变量设置为 0,并在设置的单选按钮中将值 1 分配到 4。然后我使用 command:lambda 并将所有三个变量传递给一个检查非零值的函数。如果非零,则启用提交按钮。
  • Eric:虽然您的建议肯定是可行的并且具有一定的优势,但仅禁用“提交”按钮直到可以按下它的一个微妙的缺点是没有明确的指示为什么 它处于它所处的状态。人机界面设计可能是一个棘手的主题......
  • 也许在这种情况下,可以在按钮旁边添加一个标签,以解释它被禁用的原因。启用按钮时,标签的文本可以设置为“”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-18
  • 1970-01-01
相关资源
最近更新 更多