Putting up the skeleton structure

To start, we build a class PianoTutor (7.01/view.py), the __init__ method of which is defined as follows:

class PianoTutor:

def __init__(self, root):
self.root = root
self.root.title('Piano Tutor')
self.build_mode_selector_frame()
self.build_score_sheet_frame()
self.build_controls_frame()
self.build_keyboard_frame()
self.build_chords_frame()
self.build_progressions_frame()
self.build_scales_frame()

In the preceding code, we are simply defining method calls to build multiple Frame widgets of predefined heights.  We won't elaborate much upon the preceding code as we wrote similar code in all of the previous chapters. 

Let's look at one example of frame creation. All other frames follow a similar pattern (7.01 /view.py) and will not be discussed here:

 def build_score_sheet_frame(self):
self.score_sheet_frame = Frame(self.root, width=WINDOW_WIDTH, height=
SCORE_DISPLAY_HEIGHT, background='SteelBlue1')
self.score_sheet_frame.grid_propagate(False)
Label(self.score_sheet_frame, text='placeholder for score sheet',
background='SteelBlue1').grid(row=1, column=1)
self.score_sheet_frame.grid(row=1, column=0)

This is simple Frame creation using the grid geometry manager. However, take a note of the line self.score_sheet_frame.grid_propagate(False).

In Tkinter, the container window (Frame in the previous example) is designed to shrink to fit around its contents.  

Even though we have explicitly added a  width or height to the frame, if we comment the grid_propagate(false) line, you will notice that the width and height parameters given by us are simply ignored and the frame will shrink to exactly fit its children—the Label widgets height in our case. We do not want to allow this shrinking of Frames and grid_propagate(False) lets us achieve that. 

If we were using pack manager, we would have used frame.pack_propagate(False) instead to achieve the same result.

Next, our topmost mode selector combobox is bound to the following callback (7.01/view.py):

self.mode_selector.bind("<<ComboboxSelected>>", self.on_mode_changed)

Here's how we define the on_mode_changed method (7.01/view.py):

def on_mode_changed(self, event):
selected_mode = self.mode_selector.get()
if selected_mode == 'Scales':
self.show_scales_frame()
elif selected_mode == 'Chords':
self.show_chords_frame()
elif selected_mode == 'Chord Progressions':
self.show_progressions_frame()

def show_scales_frame(self):
self.chords_frame.grid_remove()
self.progressions_frame.grid_remove()
self.scales_frame.grid()

def show_chords_frame(self):
self.chords_frame.grid()
self.progressions_frame.grid_remove()
self.scales_frame.grid_remove()

def show_progressions_frame(self):
self.chords_frame.grid_remove()
self.progressions_frame.grid()
self.scales_frame.grid_remove()

Take a note of the grid_remove() method mentioned previously. This method removes the widget from the grid manager, thereby making it invisible. You can make it visible again by using grid() on it. So effectively, whenever a user selects one of the three options (Scales, Chords, and Chord Progression) from the topmost combobox, the other two frames are hidden using grid_remove and the frame for the selected option is made visible using grid.

This completes the first iteration where we defined the broad GUI structure with the capability to switch between scales, chords, and chord progression frames based on choices made in the topmost combobox. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.37.10