1

I am trying to learn the basics of the tkinter module. I made this program where I have some questions and each question has some options. My options are displayed using radio button selection. I want to select one choice at a time for each question independently. Currently when I select the 1st option then the 1st option of every question is selected but I don't want the selection for other than the one I am on.

My second question is once the selection [is made] I want to use the selection results and compare them with the answer keys to see how many answers are correct. How do I store the user's answer for each question?

Output result:

screenshot

Edit: Sorry for not posting my code as well. Here is my python file which I am working on.

 from tkinter import *

 guessOptions =[]

 def display():
    global guessOptions
 if x.get() == 0:
    guessOptions.append("A")
 elif x.get() == 1:
    guessOptions.append("B")
elif x.get() == 2:
    guessOptions.append("C")
else:
    guessOptions.append("D")

window = Tk()
answers = ['A', 'B', 'C', 'D']
questions = ["Who invented Bulb? ",
             "Which is not passive component? ",
             "Which is not related to computer? ",
             "Opertor used for and operation? "]

options = [['A. Thomas Edison', 'B. Nikola Tesla', 'C. Albert  
           Einstien', 'D. Michael Faraday'],
           ['A. Inductor', 'B. op-amp', 'C. Capacitor', 'D. 
            Resistor'],
           ['A. RAM', 'B. SSD', 'C. Heat', 'D. Keyboard'],
           ['!', '~', '||', '&']]

x = IntVar()

for i in range(len(questions)):
    label = Label(window,
                  text=questions[i],
                  font=('Arial', 15, 'bold'))
    label.pack(anchor=W)
    for j in range(len(options)):
        checkButton = Radiobutton(window,
                                  text=options[i][j],
                                  variable=x,
                                  value=[j],
                                  padx=10,
                                  font=('Arial', 10),
                                  command=display
                                  )
        checkButton.pack(anchor=W)

window.mainloop()
Syed Ahmed
  • 25
  • 6

1 Answers1

2

Each group of answers to a question needs its own IntVar and you'll need to add a Button to trigger the answer checking process. I've done most of that in the code below, except that check_answers() function doesn't really do anything meaningful since you haven't specified exactly what would be involved (or even what the correct choices are).

from tkinter import *

guessOptions =[]

def display(x):
    global guessOptions

    if x.get() == 0:
        guessOptions.append("A")
    elif x.get() == 1:
        guessOptions.append("B")
    elif x.get() == 2:
        guessOptions.append("C")
    else:
        guessOptions.append("D")

def check_answers():
    print(f'{guessOptions=}')


window = Tk()
answers = ['A', 'B', 'C', 'D']
questions = ["Who invented bulb? ",
             "Which is not passive component? ",
             "Which is not related to computer? ",
             "Operator used for and operation? "]

options = [['A. Thomas Edison', 'B. Nikola Tesla', 'C. Albert Einstein',
            'D. Michael Faraday'],
           ['A. Inductor', 'B. Op-amp', 'C. Capacitor', 'D. Resistor'],
           ['A. RAM', 'B. SSD', 'C. Heat', 'D. Keyboard'],
           ['!', '~', '||', '&']]

variables = []
for i in range(len(questions)):
    label = Label(window, text=questions[i], font=('Arial', 15, 'bold'))
    label.pack(anchor=W)

    var = IntVar(value=-1)
    variables.append(var)  # Save for possible later use - one per question.

    def handler(variable=var):
        """Callback for this question and group of answers."""
        display(variable)

    for j in range(len(options)):
        checkButton = Radiobutton(window, text=options[i][j], variable=var,
                                  value=j, padx=10, font=('Arial', 10),
                                  command=handler)
        checkButton.pack(anchor=W)

comp_btn = Button(window, text="Check Answers", command=check_answers)
comp_btn.pack()

window.mainloop()

martineau
  • 119,623
  • 25
  • 170
  • 301
  • thank you it worked for me. I removed the variables list and it still worked because I see no use of it in the followed code. Though I have a little bit of idea that var value is set to -1 after each question but I don't understand how the handler function is working. why not just call directly display function, – Syed Ahmed Mar 06 '22 at 13:36
  • I put the `IntVar`s is the `variables` list so their values could be checked randomly at any time (if you wished to). The `handler()` function is created and given an argument with a default value as a way to pass a different `IntVar` to the `display()` function it calls — note the `x` parameter it now has (unlike your version). Using default argument values like this is a common "trick" used in order to pass the correct items as arguments to other functions (when the items are being created in a loop). – martineau Mar 06 '22 at 14:23
  • Technically your question is a duplicate of [tkinter creating buttons in for loop passing command arguments](https://stackoverflow.com/questions/10865116/tkinter-creating-buttons-in-for-loop-passing-command-arguments) and [Tkinter assign button command in a for loop with lambda](https://stackoverflow.com/questions/17677649/tkinter-assign-button-command-in-a-for-loop-with-lambda). – martineau Mar 06 '22 at 14:26
  • Advice: If you keep the `variables` list then you wouldn't need to have the `display()` function and the `guessOptions` list because you could check what choices the user has made (if any) for each question by calling the `get()` method of each `IntVar` stored in it when the `check_answers()` function is called. This was what I had in mind when I decided to save them in a list like that. – martineau Mar 09 '22 at 02:29