0

I'm creating a GUI in python using tkinter and am having trouble when running it. I have an entry box widget, a radiobutton widget, and a button widget. When I press the button, what I want is the user to type a number into the entry box and select an option from the list of radiobuttons. When the user presses the button, I'd like the values to be retrieved and displayed in the other frame for testing. What I get instead is when the button gets pressed, I get the error 'NoneType' object has no attribute 'get'. The error is referring to the value inside of the entry box: self.tune_entry

The code I have is as follows:

SA_main.py

import os
import tkinter as tk
from tkinter import ttk
from tkinter import font
import SA_gui

def main():

    x_vals = [0,1,2,3,4]
    y_vals = [0,1,2,3,4]

    root = SA_gui.tk.Tk()
    UI = SA_gui.Window(root, x_vals, y_vals)

    root.mainloop()


if __name__ == "__main__":
    main()

SA_gui.py

import os
import tkinter as tk
from tkinter import ttk
from tkinter import font

# Class to define, setup, and build the GUI
class Window:

    # Dimensions of the GUI
    HEIGHT = 600
    WIDTH = 1200

    # Colors for main layout
    bg_color = "#B0E0E6"
    frame_color1 = "#73B1B7"
    white_color = "#FFFFFF"

    def __init__(self, master, x_vals, y_vals):

        # Take in the lists of files for later use
        self.x_vals = x_vals
        self.y_vals = y_vals

        #--------------------------------------------------------------

        # Define and create the window
        self.master = master
        master.title("Signal Analysis")
        master.geometry("{}x{}".format(Window.WIDTH, Window.HEIGHT))

        # Create and place the background frame
        self.bg_frame = tk.Frame(self.master, bg=Window.bg_color, bd=5)
        self.bg_frame.place(relwidth=1, relheight=1)

        # Create the main title
        self.main_title = tk.Label(self.bg_frame, text="Software Defined Radio Signal Analysis", 
            bg=Window.bg_color, font=("Courier", 14))
        self.main_title.pack(side="top")

        #--------------------------------------------------------------

        # Create and place the frame for tuning
        self.tune_frame = tk.Frame(self.bg_frame, bg=Window.frame_color1, bd=4)
        self.tune_frame.place(relx=0.05, rely=0.1, relwidth=0.2428, relheight=0.8)

        # Create and place the title for the tuning frame
        self.tune_title = tk.Label(self.tune_frame, text="Tune", bg=Window.frame_color1, font= 
            ("Courier", 11))
        self.tune_title.place(relwidth=1, anchor="nw")

        # Create and place the contents of the tuning frame
        self.tune_cont = tk.Frame(self.tune_frame, bg=Window.white_color, bd=4)
        self.tune_cont.place(relx=0.05, rely=0.05, relwidth=0.9, relheight=0.925)

        #Label for frequency entry
        self.tune_label = tk.Label(self.tune_cont, text='Enter carrier frequency: (kHz)', 
            bg=Window.white_color)
        self.tune_label.place(relx=0.025, rely=0)

        #Entry Box for frequency entry
        self.tune_entry = tk.Entry(self.tune_cont)
        self.tune_entry.place(relx=0.025, rely=0.075, relwidth=0.95, relheight=0.05)

        #Label for divider
        self.tune_div = ttk.Separator(self.tune_cont, orient="horizontal")
        self.tune_div.place(rely=0.175, relwidth=1)

        #Label for display mode
        self.disp_label = tk.Label(self.tune_cont, text='Select Display:', bg=Window.white_color)
        self.disp_label.place(relx=0.025, rely=0.2)

        #Variable for radiobuttons
        self.var = tk.IntVar(self.tune_cont).set("1")

        #Radio Button for Spectral Analysis
        self.SA_select = tk.Radiobutton(self.tune_cont, text="Spectral 
            Analysis",bg=Window.white_color, padx=20, variable=self.var, value=1)
        self.SA_select.place(relx=0.025, rely=0.275)

        #Radio Button for Option 2
        self.opt2_select = tk.Radiobutton(self.tune_cont, text="Option 2",bg=Window.white_color, 
            padx=20, variable=self.var, value=2)
        self.opt2_select.place(relx=0.025, rely=0.35)

        #Radio Button for Option 3
        self.opt3_select = tk.Radiobutton(self.tune_cont, text="Option 3",bg=Window.white_color, 
            padx=20, variable=self.var, value=3)
        self.opt3_select.place(relx=0.025, rely=0.425)


        #Button for selection
        self.tune_button = ttk.Button(self.tune_cont, text="Enter", command=lambda: 
            self.print_selected(self.var.get(), self.tune_entry.get()))
        self.tune_button.place(relx= 0.775, rely=0.9, relwidth=0.2, relheight=0.075)

        #-----------------------------------------------------------------

        # Create and place the frame for the plot
        self.plot_frame = tk.Frame(self.bg_frame, bg=Window.frame_color1, bd=4)
        self.plot_frame.place(relx=0.3428, rely=0.1, relwidth=0.6071, relheight=0.8)

        # Create and place the title for the plot frame
        self.plot_title = tk.Label(self.plot_frame, text="Plot", bg=Window.frame_color1, font= 
            ("Courier", 11))
        self.plot_title.place(relwidth=1, anchor="nw")

        # Create and place the contents of the plot frame
        self.plot_cont = tk.Frame(self.plot_frame, bg=Window.white_color, bd=4)
        self.plot_cont.place(relx=0.025, rely=0.05, relwidth=0.95, relheight=0.925)



    def print_selected(self, disp, freq):
        if disp == 1:
            disp_mode = "Spectral Analysis"
        elif disp == 2:
            disp_mode = "Option 2"
        else:
            disp_mode = "Option 3"

        #Label for this test
        self.prnt_label = tk.Label(self.plot_cont, text="Display: " + disp_mode + ", Center Freq: " + 
            freq, bg=Window.white_color)
        self.prnt_label.place(relx=0.025, rely=0.2)

Any help to resolve this issue is greatly appreciated!

  • 1
    Please [edit] your post and add the full text of the traceback as formatted text. – MattDMo Sep 15 '20 at 20:35
  • Are you _certain_ the problem is with `self.tune_entry`? That seems highly unlikely. Instead, it should be happening on `self.var`. – Bryan Oakley Sep 15 '20 at 20:42
  • @BryanOakley I'm not certain that its `self.tune_entry` it might be `self.var`. I'll look into that too thanks! –  Sep 15 '20 at 21:06
  • @MattDMo All it says is `'NoneType' object has no attribute 'get'` on the line with the button command –  Sep 15 '20 at 21:14
  • @jstraugh Yeah, I didn't feel like reading through nearly 150 lines of code to find that one specific line. Next time, *please* include the **full text** of the traceback as formatted text *in the question itself*. Also, please read about [mre]s and post one instead of slapping a wall of irrelevant code in your question. Half the time, the process of making an MRE will lead you to the answer anyway, so it's a very worthwhile thing to do. – MattDMo Sep 16 '20 at 22:48

1 Answers1

0

Consider this code:

self.var = tk.IntVar(self.tune_cont).set("1")

Anytime you do x=y().z() python assigns the return value of z() to x. Thus, in your code you're assiging the result of .set("1") to self.var. The set method is returning None so self.var is None. Thus, when you later try to call self.var.get() it's the same as doing None.get().

If you want to initialize a variable at the time of creation, there is no need to call set. Also, while it works to pass a string, if you're setting an IntVar you really ought to be setting it to an integer.

self.var = tk.IntVar(value=1)
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685