From Apple to Raspberry Pi: Configuring Buttons for GUI.

appleberryIn our last installment, we learned how to add buttons and labels to a Python program. Now we are going to make them look a little nicer than the generic buttons we haven now using the configure method of Tkinter.

Make a beginning framework

To start, lets enter this code into a new window.

# tkinter_playbox_03
# learning about configure

from tkinter import *
root= Tk()
root.title('Tkinter Color Button Playbox')

#make a frame
rootframe = Frame(root)
rootframe.grid(row=0,column=0)

#make buttons

button1 = Button(rootframe, text = 'color')
button1.grid(row = 0, column = 0)

quitbutton = Button(rootframe, text = 'Quit', command = quit)
quitbutton.grid(row = 1, column = 0)

#main loop
root.mainloop()

Build and run this code. It should give you a window like this:
Screenshot 2014-04-13 21.05.07

Get Colorful with Configure and Background

Now, change the button1 declaration to this

button1 = Button(rootframe, text = 'color', background = 'blue')

Build and run the code changes:
Screenshot 2014-04-13 21.06.14

We added the background = 'blue' option. Not surprisingly, the button is now blue. Places we assign the parameters for the Button class we call an option in Tkinter. One good source for a list of button options is New Mexico Tech’s Tkinter 8.5 Reference. Look into the options available, but here is a list of a few we will be discussing:

  • background (also bg) – sets the background color
  • foreground – sets the text color
  • activebackground – on a mouse over, background color of the button
  • activeforeground – on a mouse over condition, text color of the button
  • command – specify a method or function to execute when button is clicked
  • text – a static title for the button
  • textvariable – link to a variable to change the title dynamically

We define colors with strings. There are several standard colors like blue, red, and green. The list of standard colors is  in the Tk documentation You can also  define a color by a hex description of RGB in the form of #rrggbb, such as #ff0000 for red.

Setting Options with Configure

We have been setting options for the button in one long string of options. That can get confusing very quickly. We can use the configure method to clean this up a bit. Change the code for button1 to this:

button1 = Button(rootframe, text = 'color')
button1.configure(background = 'blue')

Now run this, and we will find no change.
Screenshot 2014-04-13 21.06.14

Let’s add another configure method:

button1 = Button(rootframe, text = 'color')
button1.configure(background = 'blue')
button1.configure(activebackground = 'blue', activeforeground = 'white')

This code doesn’t seemingly change anything, but moves your cursor over the button. The background remains blue, but the text changes to white.

Make a Rainbow of Buttons

Now modify the code for button1 to the following:

#make buttons
colors = ('red','orange','yellow','green','blue','violet')
col=0
for color in colors:
    button1 = Button(rootframe, text = color)
    button1.grid(row = 0, column = col)
    button1.configure(background = color )
    button1.configure(activebackground = color, activeforeground = 'white')
    col=col+1

What we do here is create a immutable list of colors called a tuple. We then use a for loop to loop through the colors setting the button colors to each color in the tuple. We also created a variable col, which counts columns and places our button in the next column. Run this code, and you should see:
Screenshot 2014-04-13 21.45.42

Play with the buttons a bit, and you will see the buttons highlight with white text when you put your mouse cursor over them. However clicking the buttons doesn’t do anything. Let’s change that, by changing the color of the quit button when we click a button.

Adding Parameter Functions With lambda

In order to change the quit button, we will need a function for an event handler. Add the following:

#event handlers
def buttonPressed(buttoncolor):
    quitbutton.configure(background = buttoncolor)

There is a problem here. Our function has a parameter. We added a event handler last time using the command option. We do it in our current code with the Quit button, calling quit. However, in is simple state, command takes no parameters, and we can’t just add parameters to the function assigned to command. Instead we use this strange thing called lambda. There are a lot of explanations of what lambda really is, and Yet Another Lambda Tutorial is a really good one with links to some of the others. I’m not going to explain lambda. It has one major use for all intents and purposes and that’s getting parameters into your event handler, by wrapping your function in a way command likes. Change your code as follows:

 button1 = Button(rootframe, text = color, command = lambda color=color:buttonPressed(color))

You will see that there is a multiple use of the variable color. Due to our loop we need to make a variable within a local scope so we gt the right color. If we don’t, it will only use the last color. Run this,try pressing the buttons, and see what happens.

Make the Quit Button Bigger with Sticky and Columnspan

Our quit button is all alone on the corner. Let’s set it up to take up all the space on the bottom row. Start by changing the quitbutton code like this:

quitbutton.grid(row = 1, column = 0, columnspan = 3)

Screenshot 2014-04-13 21.54.40
The quit button moves over to the third column, but does not change its width. The option columnspan for grid tells the widget like a button to span three columns, starting at column 0. It did, but kept its size the same. We need the Xcode equivalent of a strut which is called a sticky. Stickies use the constants based on compass directions N,S,E,W for the sides of the window, and NE,NW,SE,SW for the corners. These directions can be added together. To get a columnspan to be across its entire width, make it sticky on both ends like this:

quitbutton.grid(row = 1, column = 0, columnspan = 3, sticky=E+W)

Run that code and you will see:
Screenshot 2014-04-13 21.53.32

There is several ways to get this across the whole window. I like a dynamic approach based on the number of elements in our tuple, so I can change the tuple and the quit button will respond properly:

quitbutton.grid(row = 1, column = 0, columnspan = len(colors), sticky=E+W)

Now run this:
Screenshot 2014-04-13 21.55.30

We learned a lot about buttons. However that is not the only type of input. We’ll look at text input and more with formatting labels in our next installment.

The full code for this example:

#make the window
root= Tk()
root.title('Tkinter Color Button Playbox')

#make a frame
rootframe = Frame(root)
rootframe.grid(row=0,column=0)

#event handlers
def buttonPressed(buttoncolor):
    quitbutton.configure(background = buttoncolor)

#make buttons
colors = ('red','yellow','green','cyan','blue','magenta')
col=0
for color in colors:
    button1 = Button(rootframe, text = color, command = lambda color=color:buttonPressed(color))
    button1.grid(row = 0, column = col)
    button1.configure(background = color )
    button1.configure(activebackground = color, activeforeground = 'white')
    col=col+1
quitbutton = Button(rootframe, text = 'Quit', command = quit)
quitbutton.grid(row = 1, column = 0, columnspan = len(colors), sticky=E+W)

#start the main loop
root.mainloop()

One thought on “From Apple to Raspberry Pi: Configuring Buttons for GUI.”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s