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.
Try opening the combo boxes,
Now click Add:
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.
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()
Leave a Reply