简体   繁体   中英

Tkinter: Multiple Radio Buttons

I am creating a multiple choice test and a single question will have 3 parts (only 2 shown below - will add 3rd once I get this down).

I want the user to answer all parts, then hit submit button to record answers.

I have the prompts/choices in a class.

I display the choices and radio buttons, everything works generally. When all parts were not answered, it gives a warning. However my method for this is stupid. I currently display a message and then simply overwrite it with blanks when all choices are made and button clicked again. I cannot .destroy or .remove because if my conditions were not meant, son label was created and I get an error. I should probably put the display on a timer and then remove it maybe.

Ideally, my submit button would be disabled until all choices have been made instead, but I haven't figured that out yet either.

So can you either help me handle the warning message or disable the submit button until all radio button groups have a selection?

# 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

I think the best way to solve this is by disabling the 'Submit' button until both radio inputs (3 in the future, as you say) aren't filled.

By doing some research i found how to Disable/Enable buttons and also another post for Radio button events

Basically you should have 3 boolean variables (for each group of radio buttons), have all of them set to False , and when you click to one of the buttons, you call a function that sets the variable to True (if it wasn't already), and checks if all the variables are already True , so the button can be enabled.

You may want to put these variables to global , so you can change the value.

Here's an example based on your code — with enough scaffolding to actually be runnable — that illustrates how to simply display one of the built-in tlinter.messagebox dialogs when all the choices weren't made.

An advantage of doing things this way is that it doesn't require destroying, removing, or blanking things out because that happens automatically when the user clicks the OK button acknowledging the message.

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()

Screenshot showing error dialog being displayed after clicking the button:

显示错误消息的屏幕截图


For quick reference, here's a sample of what all the other tkinter.messagebox dialogs look like:

可用对话框示例

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM