Mayukh Sarkar
Mayukh Sarkar

Reputation: 2625

How to create StringVar in a class whose Tk() is defined in some other class?

Here I need to crate a DropDown class & later add it to the root or main GUI. But Tkinter.StringVar() is throwing an error saying

`Traceback (most recent call last):
  File "D:/Testing/Tiks/main2.py", line 64, in <module>
    d = Droppy(application)
  File "D:/Testing/Tiks/main2.py", line 45, in __init__
    self.control_variable = Tkinter.StringVar()
  File "C:\Python26\lib\lib-tk\Tkinter.py", line 251, in __init__
    Variable.__init__(self, master, value, name)
  File "C:\Python26\lib\lib-tk\Tkinter.py", line 182, in __init__
    self._tk = master.tk
AttributeError: 'NoneType' object has no attribute 'tk'
Exception AttributeError: "StringVar instance has no attribute '_tk'" in <bound method StringVar.__del__ of <Tkinter.StringVar instance at 0x0236F7B0>> ignored`

My code is this

import Tkinter


class App(object):

    def __init__(self):
        self.root = Tkinter.Tk()
        ############################
        ############################
        self.root.mainloop()


class Droppy(object):

    def __init__(self, frame=None):
        # if frame is None:
        #     raise Exception
        self.frame = frame
        self.control_variable = Tkinter.StringVar()
        self.control_variable.set("Choose Options")
        self.dropDown = None

    def dropIt(self):
        self.dropDown = Tkinter.OptionMenu(self.frame.root, self.control_variable, "Rules", "Processing", "Output",
                                           "Actions")
        self.dropDown.pack()

if __name__ == '__main__':
    application = App()
    # application = Droppy()
    # application.dropIt()
    d = Droppy(application)
    d.dropIt()

Now I know that Tkinter.Tk() before Tkinter.StringVar() can solve this issue but I cannot put Tkinter.Tk() and Tkinter.StringVar()` in the same class. How can I avert this issue ? Can anyone help please

Upvotes: 0

Views: 389

Answers (2)

toti08
toti08

Reputation: 2464

As an alternative you can call your mainloop() in the main:

if __name__ == '__main__':
    application = App()
    d = Droppy(application)
    d.dropIt()
    application.root.mainloop()

Upvotes: 0

furas
furas

Reputation: 142859

mainloop is endless loop and it is running till you close Tk window.
You create Droppy when App is already closed.

You have to create object before mainloop - for example inside App.__init__.

import Tkinter


class App(object):

    def __init__(self):
        self.root = Tkinter.Tk()
        ############################
        d = Droppy(self)
        d.dropIt()
        ############################
        self.root.mainloop()


class Droppy(object):

    def __init__(self, frame=None):
        # if frame is None:
        #     raise Exception
        self.frame = frame
        self.control_variable = Tkinter.StringVar()
        self.control_variable.set("Choose Options")
        self.dropDown = None

    def dropIt(self):
        self.dropDown = Tkinter.OptionMenu(self.frame.root, self.control_variable, 
                                           "Rules", "Processing", "Output",
                                           "Actions")
        self.dropDown.pack()

if __name__ == '__main__':
    application = App()

Upvotes: 2

Related Questions