Make App Pie

Training for Developers and Artists

From Apple to Raspberry Pi: Adding Combo Box Selections and Message Boxes

We began to make our penguin data collection interface last week. Today we are going to add Combobox selections to the penguin panel.  The Combobox widget codes similar to the Entry widget. Instead of text for a title it takes a list for values. We also will add our own dialog box using the messagebox module to end the application.

Make the Combo Boxes

In loadView() Under the quitbutton code add the following:

       penguinType_values = ['Adele','Emperor','King','Blackfoot','Humboldt','Galapagos','Macaroni','Tux','Oswald Cobblepot','Flippy Slippy']
        penguinType_combobox = ttk.Combobox(values = penguinType_values, textvariable = self.penguinType)
        penguinType_combobox.grid(row =1, column = 0)

        penguinAction_values = ['Happy','Sad','Angry','Standing','Swimming','Eating','Sleeping','On Belly','Plotting Evil','Singing','Dancing','Being Cute']
        penguinAction_combobox = ttk.Combobox(values = penguinAction_values, textvariable = self.penguinAction)
        penguinAction_combobox.grid(row=1, column = 3)

This will add two combo boxes to the user interface. Lines 1 and 4 make a list of our options. Lines 2 and 5 make our combo box, using the values attributes. Lines 3 and 6 place it on the grid.

We will need a few new control variables. Add this above self.vc = MyViewController(self) in the __init__ method of MyView

        self.penguinType = StringVar()
        self.penguinType.set('Penguin Type')
        self.penguinAction = StringVar()
        self.penguinAction.set('Penguin Action')

That sets some prompts for the combo box. We only need an action to use the combo box. Change the addPressed method to

    def addPressed(self):

        self.parent.labelText.set(self.parent.penguinType.get()+ ' Penguin '+ self.parent.penguinAction.get() + ' Added')

Save and run.
Screenshot 2014-05-19 08.52.50
Try opening the combo boxes,
Screenshot 2014-05-19 08.53.12
Screenshot 2014-05-19 08.54.02
Now click Add:
Screenshot 2014-05-19 08.54.16
and the event registers.

Make a Message Box for Quitting

For the quitting, replace the quitButton target-action with this:

def quitPressed(self):
        self.view.labelText.set('Quitting')
        answer = messagebox.askokcancel('Ok to Quit','This will quit the program. \n Ok to quit?')
        if answer==True:
            self.destroy()

Also add the following import below the line for ttk

from tkinter import messagebox

While other version of Python and tkinter seem to use other import statements, only the one above seems to work on the latest version. Most of the tutorials will lead you down frustrating blind alleys, as I found out the hard way. The above code does work. Messagebox is a module with a set of methods for making dialog boxes. We need the askokcancel one. The first parameter puts a string in the title, and the second is a prompt in the window created. Note that the newline \n escape sequence works in the prompt. this method returns a boolean value. If we answered yes, it returns True. In that case we end the application using the destroy()method. Save and run. Click the Quit button.

Screenshot 2014-05-19 08.54.43

It works well. We have much of our UI in place. Next time we will go back to MVC and separate the controller from the view.

The Code, and Nothing but the Code

Here’s the code for our user interface so far:

# poppers_penguins_01
#Basic Object Oriented GUI 
from tkinter import *
from tkinter import ttk
from tkinter import messagebox


class MyViewController():
    def __init__(self,parent):
        self.parent = parent;
        
        
    #Handlers -- target action
    def addPressed(self):
        
        self.parent.labelText.set(self.parent.penguinType.get()+ ' Penguin '+ self.parent.penguinAction.get() + ' Added')
    def quitPressed(self):
        self.view.labelText.set('Quitting')
        answer = messagebox.askokcancel('Ok to Quit','This will quit the program. \n Ok to quit?')
        if answer==True:
            self.destroy()

class MyView(Frame):
  
    def __init__(self,parent):

        self.frame = Frame.__init__(self, parent, background="#5555ff", takefocus = 0)
        self.parent = parent
        self.parent.title("Popper's Penguins")
        
        self.labelText = StringVar()
        self.labelText.set("Popper's Penguins Ready")
        #some UI variables
        self.penguinType = StringVar()
        self.penguinType.set('Penguin Type')
        self.penguinAction = StringVar()
        self.penguinAction.set('Penguin Action')

        self.vc = MyViewController(self)
        self.loadView()
        self.makeStyle()
        
#Handlers -- our pseudo-controller
    def addPressed(self):
        self.labelText.set(self.penguinType.get()+ ' Penguin '+ self.penguinAction.get() + ' Added')
    def quitPressed(self):
        self.labelText.set('Quitting')
        answer = messagebox.askokcancel('Ok to Quit','This will quit the program. \n Ok to quit?')
        if answer==True:
            self.parent.destroy()
#Style Sheet
    def makeStyle(self):
        self.s = ttk.Style()
        self.s.configure('TFrame',background = '#5555ff')
        self.s.configure('TButton',background = 'blue', foreground = '#eeeeff', font = ('Sans','14','bold'), sticky = EW)
        self.s.configure('TLabel',font=('Sans','16','bold'),background = '#5555ff', foreground = '#eeeeff')
        self.s.map('TButton', foreground = [('hover','#5555ff'), ('focus', 'yellow')])
        self.s.map('TButton', background = [('hover', '#eeeeff'),('focus','orange')])
        self.s.configure('TCombobox',background = '#5555ff',foreground ='#3333ff',font = ('Sans',18))
  
#loading the view
    def loadView(self):
        #label
        status_label = ttk.Label(self.frame, textvariable = self.labelText)
        #status_label.configure(font=('Sans','16','bold'),background = 'blue', foreground = '#eeeeff')
        status_label.grid(row=0,column=0,columnspan=4,sticky=EW)

        add_button = ttk.Button(self.frame,command= self.addPressed,text = 'Add')
        add_button.grid(row = 2, column = 0)
        quit_button = ttk.Button(self.frame, command = self.quitPressed, text = 'Quit')
        quit_button.grid(row = 2, column = 3)

        penguinType_values = ['Adele','Emperor','King','Blackfoot','Humboldt','Galapagos','Macaroni','Tux','Oswald Cobblepot','Flippy Slippy']
        penguinType_combobox = ttk.Combobox(values = penguinType_values, textvariable = self.penguinType)
        penguinType_combobox.grid(row =1, column = 0)

        penguinAction_values = ['Happy','Sad','Angry','Standing','Swimming','Eating','Sleeping','On Belly','Plotting Evil','Singing','Dancing','Being Cute']
        penguinAction_combobox = ttk.Combobox(values = penguinAction_values, textvariable = self.penguinAction)
        penguinAction_combobox.grid(row=1, column = 3)
        
def main(): 
    root = Tk()
    app = MyView(root)
    root.mainloop()  


if __name__ == '__main__':
    main()  

One response to “From Apple to Raspberry Pi: Adding Combo Box Selections and Message Boxes”

  1. in python 2.7 ( aug 2015 )
    i need these import statements

    from Tkinter import *
    import ttk
    import tkMessageBox as message box

    some alterations have been done on the libraries

    Mafkaan

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 )

Facebook photo

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

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: