Adjustment to a Python Script

Liam_12 0 Tallied Votes 171 Views Share

Am at an intermediate level in python and tkinter, and have been trying to figure out how to get the code below into some kind of workable form I can understand.

What I want to do is, like, if I typed something into the bottom frame, then I'd like to save it to a file.

Conversely, if I saved it, then I'd like to be able to open the file back up again, and get the values into the correct frames/widgets.

I got the code off of this website: https://code.activestate.com/recipes/578911-accordion-widget-tkinter/

The part I dont get is each class' init line. I'm very average at OOP, but the lines:

class Chord(Frame):
'''Tkinter Frame with title argument'''
def __init__(self, parent, title='', *args, **kw):
    Frame.__init__(self, parent, *args, **kw)
    self.title = title

class Accordion(Frame):
def __init__(self, parent, accordion_style=None):
    Frame.__init__(self, parent)

They seem a bit too advanced even for tkinter. Can someone help me please with how this is supposed to work?

It's a nice piece of technology, but I dont understand how it would be embedded in a more "standard" tkinter or OOP framework.

'''The Accordion widget inherits from Tkinter's Frame class and provides stacked
expandable and collapseable containers for displaying other widgets.

Compliant with Python 2.5-2.7

Author: @ifthisthenbreak
'''

from Tkinter import Tk, Frame, PhotoImage, Label


class Chord(Frame):
    '''Tkinter Frame with title argument'''
    def __init__(self, parent, title='', *args, **kw):
        Frame.__init__(self, parent, *args, **kw)
        self.title = title

class Accordion(Frame):
    def __init__(self, parent, accordion_style=None):
        Frame.__init__(self, parent)

        # if no style dict, assign default style
        if accordion_style:
            self.style = accordion_style
        else:
            self.style = accordion_style = {
                'title_bg': 'ghost white',
                'title_fg': 'black',
                'highlight': 'white smoke'
                }
        
        self.columnconfigure(0, weight=1)
        
    def append_chords(self, chords=[]):
        '''pass a [list] of Chords to the Accordion object'''

        self.update_idletasks()
        row = 0
        width = max([c.winfo_reqwidth() for c in chords])
        
        for c in chords:
            i = PhotoImage() # blank image to force Label to use pixel size
            label = Label(self, text=c.title,
                          image=i,
                          compound='center',
                          width=width,
                          bg=self.style['title_bg'],
                          fg=self.style['title_fg'],
                          bd=2, relief='groove')
            
            label.grid(row=row, column=0)
            c.grid(row=row+1, column=0, sticky='nsew')
            c.grid_remove()
            row += 2
            
            label.bind('<Button-1>', lambda e,
                       c=c: self._click_handler(c))
            label.bind('<Enter>', lambda e,
                       label=label, i=i: label.config(bg=self.style['highlight']))
            label.bind('<Leave>', lambda e,
                       label=label, i=i: label.config(bg=self.style['title_bg']))
                       
    def _click_handler(self, chord):
        if len(chord.grid_info()) == 0:
            chord.grid()
        else:
            chord.grid_remove()
        
            
if __name__ == '__main__':
    from Tkinter import Entry, Button, Text


    root = Tk()

    # create the Accordion
    acc = Accordion(root)
    
    # first chord
    first_chord = Chord(acc, title='First Chord', bg='white')
    Label(first_chord, text='hello world', bg='white').pack()

    # second chord
    second_chord = Chord(acc, title='Second Chord', bg='white')
    Entry(second_chord).pack()
    Button(second_chord, text='Button').pack()

    # third chord
    third_chord = Chord(acc, title='Third Chord', bg='white')
    Text(third_chord).pack()

    # append list of chords to Accordion instance
    acc.append_chords([first_chord, second_chord, third_chord])
    acc.pack(fill='both', expand=1)

    root.mainloop()
Husoski 60 Newbie Poster

First things first, if you want to get that working on a modern Python installation, change all occurrences of "Tkinter" to "tkinter". All standard module and package names are lowercase in Python 3. I don't see any other 2-vs-3 problems; and after that change the code runs in my Python 3.8 installation with no obvious errors.

I don't know if this particular widget is going to be exactly what you need, but I can try to explain the __init__ stuff. It's really simple OOP inheritance. The Accordion class inherits from Frame. That makes any Accordion object a specialized version of a Frame object. When an Accordion object is created, the __init__ function in Accordion is called to intialize it. That method needs to ensure that any base classes get initialized with whatever information they need. That's what base class (aka "superclass") constructor calls do.

The Frame.__init__(self, parent) call you're looking at is old-style Python syntax for initializing a base class (aka "superclass"). It's more common to write that as super().__init__(parent) in the usual case there's only one base class. Both ways work in this code and the idea is to tell the Frame object what its parent object is. The super function actually takes two arguments. Both are using default values in that second call, but you may also see that second form written with explicit values: super(self, Frame).__init__(parent). All three versions do the same thing: Call the superclass's __init__ function to see that it gets the values it needs to initialize its part of the final object.

Final note: Python doesn't generate "default" constructor calls like some other languages (like Java or C++) do. If you use inhertitance, you must explicitly initialize your base class(es), and do so before calling any member functions on that object.

commented: Thank you for this response. Am still working to understand it. Trying to figure out how to capture the data in each part of the accordion, as it is. +0
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.