Bottom Page

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
 Using Tkinter widgets on child window
#1
Main/Root Window

My issue is in the TopLevel/Secondary Window. In that class, I have a ListBox which I can declare successfully and will appear, but my end goal is to have a button on that screen call a secondary function which will then populate the Listbox with some data from a DB.

Before tackling the database logic I tried to simply just put some data in manually using the below method:
self.Lb1.insert(END, "Entry Value")
But for some reason, it doesn't recognize that command which results in the following error
AttributeError: 'NoneType' object has no attribute 'insert'

Any help would be appreciated :)

from tkinter import *
from tkinter import ttk

class Application(object):
    def __init__(self, master):
        self.topColor = '#f2f2f2'
        self.bottomColor = '#e6e6e6'

        self.master = master

        # Configure our menu
        menu = Menu(self.master)
        self.master.config(menu = menu)

        file = Menu(menu, tearoff = 0)
        file.add_command(label = 'About', command = self.aboutMessage)
        file.add_command(label = 'Exit', command = self.client_exit)
        menu.add_cascade(label = 'File', menu = file)

        edit = Menu(menu, tearoff = 0)
        edit.add_command(label = 'Undo')
        menu.add_cascade(label = 'Edit', menu = edit)

        rules = Menu(menu, tearoff = 0)
        rules.add_command(label = 'Add Table & Function', command = self.addFuncTable)
        rules.add_command(label = 'Search', command = self.search)
        menu.add_cascade(label = 'Rules', menu = rules)

        # ---- Top Frame ---- #
        # Configure frames
        self.top = Frame(master, height = 71, bg = self.topColor)
        self.top.pack(fill = X)
        self.bottom = Frame(master, height = 530, bg = self.bottomColor)
        self.bottom.pack(fill = X)

        self.top_image = PhotoImage(file ='Images/Logo.png')
        Label(self.top, image = self.top_image).place(x = -1, y = -1)

        Label(self.top, text = "H03 & HF9 Mosaic Script Generation Tool", bg = self.topColor, font = ('Calbri', 11)).place(x = 70, y = 5)
        Label(self.top, text = 'Use the below entry boxes to fill in the necessary information about your ITR', bg = self.topColor).place(x = 70, y = 30)
        Label(self.top, text = 'This will include your Version Number(s), GUID, etc', bg = self.topColor).place(x = 70, y = 48)

        # ---- Bottom Frame ---- #

        # Define var's for each of our fields so we can get the value
        self.entry_appendixPath = StringVar()
        self.entry_rateSheetPath = StringVar()


        Label(self.bottom, text = 'File Path for Appendix:', bg = self.bottomColor).place(x = 4, y = 20)
        self.appendix = ttk.Entry(self.bottom, width = 30, textvariable = self.entry_appendixPath).place(x = 7, y = 40)

        Label(self.bottom, text = "File Path for Rate Sheet:", bg = self.bottomColor).place(x = 250, y = 20)
        self.rateSheet = ttk.Entry(self.bottom, width = 30, textvariable = self.entry_rateSheetPath).place(x = 253, y = 40)

        Label(self.bottom, text = "Script Author:", bg = self.bottomColor).place(x = 4, y = 80)
        ttk.Entry(self.bottom).place(x = 7, y = 100)

        Label(self.bottom, text = "GUID Identifier:", bg = self.bottomColor).place(x = 170, y = 80)
        ttk.Entry(self.bottom).place(x = 173, y = 100)

        self.StateCodeVal = StringVar()
        Label(self.bottom, text = "State Code:", bg = self.bottomColor).place(x = 350, y = 80)
        ttk.Combobox(self.bottom, textvariable = self.StateCodeVal, width = 10, values = [
            "PA", "AK", "AZ", "AR", "CA", "CO", "CT", "DC", "DE", "FL", "GA",
            "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA",
            "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY",
            "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX",
            "UT", "VT", "VA", "WA", "WV", "WI", "WY"
        ]).place(x = 353, y = 100)

        Label(self.bottom, text = "Current Version", bg = self.bottomColor).place(x = 4, y = 135)
        ttk.Entry(self.bottom).place(x = 7, y = 155)

        Label(self.bottom, text = "New Version:", bg = self.bottomColor).place(x = 170, y = 135)
        ttk.Entry(self.bottom).place(x = 173, y = 155)

        Label(self.bottom, text = "UW Company:", bg = self.bottomColor).place(x = 350, y = 135)
        ttk.Entry(self.bottom, width = 10).place(x = 353, y = 155)

        Button(self.bottom, text="Lookup Version", command=self.lookupOldVersion).place(x=6, y=180)

        # Not an easy way to execute a stored proc in python with OUTPUT params
        # Button(self.bottom, text="Generate").place(x = 173, y = 180)

        Label(self.bottom, text="Above button call requires that both State Code and Apex Flag are valued!", bg = self.bottomColor, fg="Red").place(x = 4, y = 210)

        self.ApexCheck = StringVar()
        Label(self.bottom, text="Apex Flag ( 1 -> is Apex, 0 -> Legacy):",
              bg=self.bottomColor).place(x = 4, y = 250)
        ttk.Combobox(self.bottom,  textvariable=self.ApexCheck, width = 10, values = [
           1, 2
        ]).place(x = 4, y = 272)

        Label(self.bottom, text = "Do we need to create new procedure(s) or table(s) for this ITR?", bg = self.bottomColor).place(x = 4, y = 310)

        # Set style for ttk.RadioButton since bg= is not supported
        s = ttk.Style()
        s.configure(
            'myStyle.TRadioButton',
            background = self.bottomColor
        )

        self.newCheck = IntVar()
        ttk.Radiobutton(self.bottom, text = "Yes", variable = self.newCheck, value = 1).place(x = 5, y = 335)
        ttk.Radiobutton(self.bottom, text = "No", variable = self.newCheck, value = 0).place(x = 5, y = 360)

        # Radiobutton(self.bottom, text = "Yes", bg = self.bottomColor, variable = newCheck, value = 1).place(x = 4, y = 270)
        # Radiobutton(self.bottom, text = "No", bg = self.bottomColor, variable = newCheck, value = 0).place(x = 4, y = 290)

        # Checkbutton(self.bottom, bg = self.bottomColor, text = "Yes", variable = newCheck).place(x = 4, y = 270)

        Button(self.bottom, text = 'Submit', fg = 'white', bg = '#00802b', command = self.getEntries).place(x = 4 , y = 400)


    def search(self):
        S = Search.Search()


def main():
    root = Tk()
    app = Application(root)
    root.title('Main Window')
    root.geometry('500x600')
    root.resizable(False, False)
    root.mainloop()

if __name__ == '__main__':
    main()
Second Window

# Tkinter modules
from tkinter import *
from tkinter import ttk
from tkinter import messagebox

class Search(Toplevel):
    def __init__(self):
        Toplevel.__init__(self)

        self.geometry('500x500')
        self.title('Search')
        self.resizable(False, False)

        self.topColor = '#f2f2f2'
        self.bottomColor = '#e6e6e6'

        # Configure frames
        self.top = Frame(self, height=71, bg=self.topColor)
        self.top.pack(fill=X)
        self.bottom = Frame(self, height=430, bg=self.bottomColor)
        self.bottom.pack(fill=X)

        self.top_image = PhotoImage(file='Images/Logo.png')
        Label(self.top, image=self.top_image).place(x=-1, y=-1)

        Label(self.bottom, text="Current Version:", bg=self.bottomColor).place(x = 5, y = 15)
        ttk.Entry(self.bottom).place(x = 7, y = 35)

        Label(self.bottom, text="New Version:", bg=self.bottomColor).place(x = 150, y = 15)
        ttk.Entry(self.bottom).place(x = 153, y = 35)

        Button(self.bottom, text = "Get Existing Rules ..").place(x = 5, y = 65)

        self.Lb1 = Listbox(self.bottom).place(x = 5, y = 140)


    def updateListBox(self):
        pass
Quote
#2
you are missing a pack command for self.Lb1
Quote
#3
I tried using the .pack() method, but I still can't get the .insert() to work (Usually the methods associated with the Listbox comes up after I type variableName.). I can, however, do this in my main.py file without any issue. I am guessing this is because I define root = Tk() and then pass that to my Application class.

Is my other class not inheriting the Tk()?
Quote
#4
I don't see anywhere in your code where one class creates an instance of the other.
in addition, the module containing the class must be imported.
-- Edit --
I see here:
    def search(self):
        S = Search.Search()
but still no import, and this is not the proper way to create the instance of search as a new instance will be created every time search is called
Quote
#5
Totally forgot to include my imports in the original post which is below:

# Misc & load functions from other file
import pyodbc
import AddTableAndFunction, Search
import RatingRule
What would be the proper way to create an instance of my Search class?
Quote
#6
instantiate in the __init__ clause of 1st program (you never specified name):
from tkinter import *
from tkinter import ttk
from Search import Search
 
class Application(object):
    def __init__(self, master):
        self.search = Search()
but you also need to separate the __init__ stuff from
procedure. create a method (def) (in Search.py) for the actual search operation
then once instantiated as above, to search something use
self.search.new_method_name(attributes) (use whatever you called new method)
Quote
#7
This thread is a bit stale but since I just wasted over an hour on the same issue I feel I should remind all us Tkinter users (Guido help us!) about this gotcha.
self.Lb1 = Listbox(self.bottom).place(x = 5, y = 140)
Does NOT assign self.Lb1 to the Listbox object! It assigns it to the output of the .place() function. Which is "None", so pretty useless. Always do your Geometry Manager stuff (.grid, .pack or .place) on a separate line when you're assigning the object so you don't fall into this trap:
self.Lb1 = Listbox(self.bottom)
self.Lb1.place(x = 5, y = 140)
It means more: Type Type Type
But much less: Smash Smash Smash
"So, brave knights, if you do doubt your courage or your strength, come no further, for death awaits you all with nasty, big, pointy teeth!" - Tim the Enchanter
Quote
#8
Quote:Does NOT assign self.Lb1 to the Listbox object! It assigns it to the output of the .place() function. Which is "None"
I find this hard to believe as I have been using tkinter for years and have never seen this.
That being said, I never combine a widget definition and a geometry on the same line but rather like your second snippet.
Quote
#9
Yeah, strange but true: https://stackoverflow.com/questions/2855...x-elegance

It's also the reason why the OP is getting his: AttributeError: 'NoneType' object has no attribute 'insert'
Because on line 34 in his Second Window code he's in-lining the .place() function so now his self.Lb1 object is of type: None.

self.Lb1 = Listbox(self.bottom).place(x = 5, y = 140)
It's bitten me several times since I tend to favor compact, in-lined code.

Quick example code:
from tkinter import * # Just quick example code.  Star imports are not a good idea!
master = Tk()

btn1 = Button(master, text="ONE")
btn1.pack()

btn2 = Button(master, text="TWO").pack()

print(type(btn1))
print(type(btn2))

<class 'tkinter.Button'>
<class 'NoneType'>

Process finished with exit code 0  
"So, brave knights, if you do doubt your courage or your strength, come no further, for death awaits you all with nasty, big, pointy teeth!" - Tim the Enchanter
Quote

Top Page

Possibly Related Threads...
Thread Author Replies Views Last Post
  Transfer Toplevel window entry to root window entry with TKinter HBH 0 915 Jan-23-2020, 09:00 PM
Last Post: HBH
  [Tkinter] Mouse click event not working on multiple tkinter window evrydaywannabe 2 425 Dec-16-2019, 04:47 AM
Last Post: woooee
  [Tkinter] Window geometry appears different on Win and Linux steve_shambles 6 449 Nov-29-2019, 12:30 AM
Last Post: steve_shambles
  tkinter window and turtle window error 1885 3 599 Nov-02-2019, 12:18 PM
Last Post: 1885
  [Tkinter] Extrakt a Variable from a closed tkinter window hWp 5 561 Aug-23-2019, 09:01 PM
Last Post: woooee
  [Tkinter] Tkinter window pop up again when i click button Orimura_Sandy 1 901 May-12-2019, 08:17 PM
Last Post: joe_momma
  [Tkinter] text widgets-insert problem genc74 3 779 Apr-27-2019, 04:00 PM
Last Post: Yoriz
  [Tkinter] Toplevel window and global widgets? KevinBrown 3 1,099 Apr-25-2019, 06:02 PM
Last Post: Yoriz
  [Tkinter] Top Level Window - from tkinter import * francisco_neves2020 6 772 Apr-23-2019, 09:27 PM
Last Post: francisco_neves2020
  tkinter- adding a new window after clicking a button built on the gui ShashankDS 2 2,175 Apr-18-2019, 12:48 PM
Last Post: ShashankDS

Forum Jump:


Users browsing this thread: 1 Guest(s)