#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Location
    California, USA
    Posts
    78
    Rep Power
    2

    Class Inheritance - How to make it work


    My first try at class inheritance produces this error:
    class inherited_form(base_form):
    TypeError: module.__init__() takes at most 2 arguments (3 given)

    I'm trying to use a form from a base class for more than one purpose,
    such as one form for viewing and one for editing.
    I need help in getting past this first hurdle. I expect the
    solution to display just the secondary form in a window,
    and not a separate window with the base form underneath it.

    Code:
    #base_form.py
    
    try:
        from Tkinter import *     ## Python 2.x
    except ImportError:
        from tkinter import *     ## Python 3.x
    
    root = Tk()
    root.geometry('400x400+20+20')
    
    class base_form(object):
    
        def __init__(self, root):
    
            label = Label(root, text='Viewing', width=14, font=('Helvetica', 16),
                bg='grey90')
            label.place(x=100, y=20)
    
            self.frame = Frame(root, borderwidth=1, relief=GROOVE)
            self.frame.place(x=50, y=60)
            
            self.scrollbar = Scrollbar(self.frame, orient=VERTICAL,
                command=self.onVsb)
            self.scrollbar.pack(side=RIGHT, fill=Y)
           
            self.lbox = Listbox(self.frame, width=25, font=('Helvetica', 14))
            self.lbox.pack(side=LEFT, fill=Y)      
            self.lbox.configure(yscrollcommand=self.scrollbar.set)
            
            self.b1 = Button(root, text='Button1', font=('Helvetica', 15),
                command='')
            self.b1.place(x=145, y=340)
    
        def onVsb(self, *args):
            self.lbox.yview(*args)
            
    #app = base_form(root)
    #root.mainloop()
    Code:
    try:
        from Tkinter import *     ## Python 2.x
    except ImportError:
        from tkinter import *     ## Python 3.x
    
    import base_form
    
    root = Tk()
    root.geometry('400x400+20+20')
    
    class inherited_form(base_form):
    
        def __init__(self):
    
            base_form.label['text']='Editing'
                            
    app = inherited_form(root)
    root.mainloop()
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,996
    Rep Power
    481
    The main program says
    Code:
    import base_form
    ###
    class inherited_form(base_form):
    but base_form is a module, not a class, so you and I can't inherit from it. Thus you can instead write this which you probably want
    Code:
    class inherited_form(base_form.base_form):
    which will bring you immediately to a different error in which you pass the argument root to the constructor of this class which takes no arguments and the chain of errors grows and I can no longer imagine what you intend.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Location
    California, USA
    Posts
    78
    Rep Power
    2
    b4... What I am trying to learn can be seen by running the 2 code
    examples that import base_form.py.
    Code should be stored in 3 separate modules. I would appreciate
    your advice or correction on how class inheritance is accomplished
    with tkinter forms across modules.

    The glitch with this code is that the base_form.py module opens up a blank window.

    Code:
    #base_form.py
    
    try:
        from Tkinter import *     ## Python 2.x
    except ImportError:
        from tkinter import *     ## Python 3.x
    
    root = Tk()
    root.geometry('400x400+20+20')
    
    class base_form(object):
    
        def __init__(self, root):
    
            self.label = Label(root, text='', width=14, font=('Helvetica', 16),
                bg='grey90')
            self.label.place(x=100, y=20)
    
            self.frame = Frame(root, borderwidth=1, relief=GROOVE)
            self.frame.place(x=50, y=60)
            
            self.lbox = Listbox(self.frame, width=25, font=('Helvetica', 14))
            self.lbox.pack(side=LEFT, fill=Y)      
            
            self.btn1 = Button(root, text='Done', font=('Helvetica', 15),
                padx=4, pady=4, command=root.destroy)
            self.btn1.place(x=30, y=340)
    
            self.btn2 = Button(root, text='Delete', font=('Helvetica', 15),
                padx=4, pady=4, command=self.delete_item)
            self.btn2.place(x=160, y=340)
    
            self.btn3 = Button(root, text='Save & Exit', wraplength=60,
                font=('Helvetica', 15), command=root.destroy)
            self.btn3.place(x=310, y=324)
    
        def delete_item(self):
            item_selected = self.lbox.curselection()
            if len(item_selected) != 0:
                self.lbox.delete(int(item_selected[0]))
    Code:
    try:
        from Tkinter import *     ## Python 2.x
    except ImportError:
        from tkinter import *     ## Python 3.x
    
    import base_form
    
    root = Tk()
    root.geometry('400x400+20+20')
    
    class inherited_form1(base_form.base_form):
        
        def __init__(self, object):
            base_form.base_form.__init__(self, root)
    
            for name in ['eggs', 'spam', 'ham', 'sausage', 'hash-browns', 'toast']:
                self.lbox.insert(END, name)
        
            self.label['text']='Editing'
            self.btn1.destroy()
           
    app = inherited_form1(root)
    root.mainloop()
    Code:
    try:
        from Tkinter import *     ## Python 2.x
    except ImportError:
        from tkinter import *     ## Python 3.x
    
    import base_form
    
    root = Tk()
    root.geometry('400x400+20+20')
    
    class inherited_form2(base_form.base_form):
        
        def __init__(self, object):
            base_form.base_form.__init__(self, root)
    
            for name in ['eggs', 'spam', 'ham', 'sausage', 'hash-browns', 'toast']:
                self.lbox.insert(END, name)
        
            self.label['text']='Viewing'
            self.lbox.config(fg='blue')
            self.btn2.destroy()
            self.btn3.destroy()
           
    app = inherited_form2(root)
    root.mainloop()
    Last edited by pyJer; October 13th, 2013 at 07:43 PM.
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,996
    Rep Power
    481
    You've put a top level widget in base_form.py as well as into the viewer and editor modules. On my computer configuration the empty window occludes the window you want to see. Let's avoid making the empty window.
    Code:
    # view.py
    try:
        from Tkinter import *     ## Python 2.x
    except ImportError:
        from tkinter import *     ## Python 3.x
    
    import base_form
    
    class inherited_form2(base_form.base_form):
        
        def __init__(self, root):
            base_form.base_form.__init__(self, root)
    
            for name in ['eggs', 'spam', 'ham', 'sausage', 'hash-browns', 'toast']:
                self.lbox.insert(END, name)
        
            self.label['text']='Viewing'
            self.lbox.config(fg='blue')
            self.btn2.destroy()
            self.btn3.destroy()
           
    root = Tk()
    root.geometry('400x400+20+20')
    
    app = inherited_form2(root)
    root.mainloop()
    Code:
    # base_form.py
    try:
        from Tkinter import *     ## Python 2.x
    except ImportError:
        from tkinter import *     ## Python 3.x
    
    class base_form(object):
    
        def __init__(self, root):
    
            self.label = Label(root, text='', width=14, font=('Helvetica', 16),
                bg='grey90')
            self.label.place(x=100, y=20)
    
            self.frame = Frame(root, borderwidth=1, relief=GROOVE)
            self.frame.place(x=50, y=60)
            
            self.lbox = Listbox(self.frame, width=25, font=('Helvetica', 14))
            self.lbox.pack(side=LEFT, fill=Y)      
            
            self.btn1 = Button(root, text='Done', font=('Helvetica', 15),
                padx=4, pady=4, command=root.destroy)
            self.btn1.place(x=30, y=340)
    
            self.btn2 = Button(root, text='Delete', font=('Helvetica', 15),
                padx=4, pady=4, command=self.delete_item)
            self.btn2.place(x=160, y=340)
    
            self.btn3 = Button(root, text='Save & Exit', wraplength=60,
                font=('Helvetica', 15), command=root.destroy)
            self.btn3.place(x=310, y=324)
    
        def delete_item(self):
            item_selected = self.lbox.curselection()
            if item_selected:
                self.lbox.delete(int(item_selected[0]))
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Location
    California, USA
    Posts
    78
    Rep Power
    2
    b4... That works, removing root = Tk() from a module from which I do not want
    to create a window. I also learned that the len() function is not needed to test
    whether or not a tuple or list object has any values, as in the line of code you changed to:
    if item_selected:

    Comments on this post

    • b49P23TIvg agrees : You've got it!
    Last edited by pyJer; October 14th, 2013 at 12:18 PM.

IMN logo majestic logo threadwatch logo seochat tools logo