Completing the pattern editor

In the preceding iteration, we coded a dummy create_right_pad with four columns of buttons. However, in the scheme of our program, the number of columns of buttons depends upon the choice of Units and beats per units (BPU) values selected by the end user.

The number of columns of buttons should be equal to:

Number of Units x BPU

Furthermore, to demarcate each unit, each consecutive unit of buttons should be displayed in different colors. Moreover, when a button is clicked, its color should change to track the user-defined pattern, as shown in the following screenshot:

Completing the pattern editor

Let us add these three features to our drum editor.

Engage Thrusters

  1. First, we will start by connecting buttons to the Units and BPU Spinbox widgets. The code is simple. We add command callbacks from both the Spinbox widgets in the top bar to call our create_right_pad method. Refer to the code in 3.03.py:
    self.units_widget = Spinbox(topbar_frame, from_=1, to=8, width=5, textvariable=self.units, command= self.create_right_pad)
    self.bpu_widget = Spinbox(topbar_frame, from_=1, to=10, width=5, textvariable=self.bpu, command= self.create_right_pad)

    We then modify our existing create_right_pad method as follows, and in code 3.03.py:

    def create_right_pad(self):
      bpu = self.bpu.get()
      units = self.units.get()
      c = bpu * units
      right_frame = Frame(self.root)
      right_frame.grid(row=10, column=6,sticky=W+E+N+S, padx=15, pady=2)
      self.button = [[0 for x in range(c)] for x inrange(MAX_DRUM_NUM)]
      for i in range(MAX_DRUM_NUM):
        for j in range(c):
          color = 'grey55' if (j/bpu)%2 else 'khaki'
          self.button[i][j] = Button(right_frame,  bg=color, width=1, command=self.button_clicked(i,j,bpu))
          self.button[i][j].grid(row=i, column=j)

    The description of the code is listed as follows:

    • Within our frame right_frame, we iterate through a double-nested loop creating a two-dimensional matrix where the number of rows is equal to the constant MAX_DRUM_NUM, while the number of columns is equal to the product of Units and BPU.
    • The color of each button is configured to either grey55 or khaki depending on whether the factor j/bpu is even or odd.
    • Now if you run the code (code 3.03.py), you will find the number of buttons changing as per selections you make in the units and bpu spin boxes. Moreover, each unit will be colored alternately in khaki and gray colors.
    • Notice how we have defined the grid geometry position of buttons in terms of variables i and j.
  2. Now that the buttons respond to change in units and bpu, it is time that we change these buttons into toggle buttons. When a user clicks on any of the buttons, the color of the button should change to green. When the button is clicked again, the color reverts to its original color. We need this feature to define beat patterns.

    We first add a command callback to our buttons, passing the button's row, column, and bpu as arguments to a new method button_clicked (refer to the code in 3.03.py), as shown in the following code:

    self.button[i][j] = (Button(right_frame, bg='grey55', width=1, command=self.Button_clicked(i,j,bpu)))

    We then define the button_clicked method as follows:

    def button_clicked(self,i,j,bpu):
      def callback():                 
        btn = self.button[i][j]
        color = 'grey55' if (j/bpu)%2 else 'khaki'
        new_color = 'green' if btn.cget('bg') != 'green' else color
        btn.config(bg=new_color)
      return callback

    The description of the code is listed as follows:

    • Our method button_clicked takes three arguments: i, j, and bpu.
    • The variables i and j let us track which button is clicked. However, note that the command callback self.Button_clicked(i,j,bpu) makes a reference to i and j when the button is not yet created. In order to track the button that is clicked by the user, we enclose a separate callback() function within our self.button_clicked function, which then returns a callback. Now our method will return a different value of i and j for each button record.
    • The bpu argument is needed to calculate the original color of the button. This is needed to revert the color of button back to its original color if the button is toggled. Before we change the color of the button to green, we store its original color in a variable color.

Objective Complete – Mini Debriefing

We have now completed coding the right drum pad. In the process we have created a two-dimensional list of buttons self.button, where self.button[i][j] refers to the button at the ith row and jth column.

Each of these buttons can be toggled on or off to represent whether or not a drum sample is to be played for that particular button.

When a button is on, its color changes to green. If it is switched off, it reverts to its original color. This structure can be easily used to define a beat pattern.

In the process, we have seen more advanced usage of the Spinbox and Button widget.

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

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