Home > front end >  StringVar.get() doesn't seem to be entirely working (Tkinter)
StringVar.get() doesn't seem to be entirely working (Tkinter)

Time:05-18

The relevant code is this:

import tkinter as tk
from tkinter import ttk
import quiz

global menu_root

def get_question():
    question_input = question_response.get()
    answer_input = answer_response.get()
    quiz.add_question(question_input, answer_input)

def question_menu():
    menu_root = tk.Tk()
    global question_response
    global answer_response
    menu_root.geometry("250x250")
    menu_root.resizable(width=False, height=False)
    menu_root.title("Add A Question!")
    question_response = tk.StringVar()
    answer_response = tk.StringVar()
    tk.Label(menu_root, text="What question would you like to add?",
             font=("TkDefault", 10)).place(x=15, y=25)
    text1 = tk.Entry(menu_root,)
    text1.place(x=15, y=45)
    tk.Label(menu_root, text="What's the answer to the question?",
             font=("TkDefault", 10)).place(x=15, y=60)
    text2 = tk.Entry(menu_root)
    text2.place(x=15, y=80)
    tk.Button(menu_root, text="Confirm?", font=("TkDefault", 10),
              command=get_question).place(x=15, y=100)
    menu_root.mainloop()

and

import tkinter as tk
from tkinter import ttk
import buttons
import quiz

def add_button_gui():
    buttons.question_menu()

def dev():
    print(quiz.Quiz.questions)
    print(quiz.Quiz.answers)

def main_gui():
    main_root = tk.Tk()
    main_root.resizable(width=False, height=False)
    main_root.geometry("500x500")
    main_root.title("Pyquiz")
    main_window = tk.Frame(main_root, borderwidth=5, relief="raised")
    main_label = tk.Label(main_root, text="PyQuiz", 
                          font=("TkDefault", 35)).place(x=165, y=0)
    add_button = tk.Button(main_root, text="Add A Question", font=("TkDefault", 25), 
                           command=add_button_gui).place(x=125, y=115)
    remove_button = tk.Button(main_root, text="Remove Latest Question", 
                            font=("TkDefault", 25)).place(x=70, y=200)
    test_button = tk.Button(main_root, text="Test Your Knowledge", 
                            font=("TkDefault", 25)).place(x=90, y=285)
    save_button = tk.Button(main_root, text="Save Questions", 
                            font=("TkDefault", 25)).place(x=110, y=375)
    dev_button = tk.Button(main_root, text="DEVTEST", font=("TkDefault", 25), 
                           command=dev).place(x=100, y=450)
    main_root.mainloop()

Now, what I want the code to do is open the second menu (menu_root) and have the user have 2 input slots which when the button is pressed it takes whatever string is in the input and adds it to a list I have in another script (quiz.Quiz.questions and quiz.Quiz.answers).

Apologies if this code is a bit sloppy but its my first real program I'm trying so it's a W.I.P. If you have any criticization or suggestions feel free (though this is also simply for a computer science class final where I am trying way too hard for no reason).

Also currently it just gives the error code of:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1264.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "C:\Users\heath\PycharmProjects\pythonProject\PyQuiz\buttons.py", line 11, in get_question
    question_input = question_response.get(question_response)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1264.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 544, in get
    value = self._tk.globalgetvar(self._name)
AttributeError: 'NoneType' object has no attribute 'globalgetvar'

Process finished with exit code 0

CodePudding user response:

I think I was able to get the code currently in your question (using two Tk()s) working by changing how the StringVars are created and adding a reference to them when the two Entry widgets are created. I've indicated the important changes in the code below with <-- CHANGED comments. Note I disabled references to the quiz module since you didn't provide the code for it in your question.

buttons.py file:

import tkinter as tk
from tkinter import ttk
#import quiz

global menu_root

def get_question():
    question_input = question_response.get()
    print(f'{question_input=!r}')
    answer_input = answer_response.get()
    print(f'{answer_input=!r}')
#    quiz.add_question(question_input, answer_input)

def question_menu():
    menu_root = tk.Tk()
    global question_response
    global answer_response
    menu_root.geometry("250x250")
    menu_root.resizable(width=False, height=False)
    menu_root.title("Add A Question!")
    question_response = tk.StringVar(master=menu_root)  # <-- CHANGED
    answer_response = tk.StringVar(master=menu_root)    # <-- CHANGED
    tk.Label(menu_root, text="What question would you like to add?", font=("TkDefault", 10)).place(
        x=15, y=25)
    text1 = tk.Entry(menu_root, textvariable=question_response)  # <-- CHANGED
    text1.place(x=15, y=45)
    tk.Label(menu_root, text="What's the answer to the question?", font=("TkDefault", 10)).place(
        x=15, y=60)
    text2 = tk.Entry(menu_root, textvariable=answer_response)  # <-- CHANGED
    text2.place(x=15, y=80)
    tk.Button(menu_root, text="Confirm?", font=("TkDefault", 10),
              command=get_question).place(x=15, y=100)
    menu_root.mainloop()

CodePudding user response:

You have to use the StringVar object that you've created as the text variable holder:

text1 = tk.Entry(menu_root, textvariable=question_response)

and:

text2 = tk.Entry(menu_root, textvariable=answer_response)

And to use global the variable has to be introduced outside the function.

  • Related