Skip to content

Commit c4aa6e5

Browse files
committed
change script name to banana_survey.py
1 parent 03bdc98 commit c4aa6e5

File tree

1 file changed

+171
-0
lines changed

1 file changed

+171
-0
lines changed

Chapter01/banana_survey.py

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
"""A banana preferences survey written in Python with Tkinter"""
2+
3+
import tkinter as tk
4+
5+
# Create the root window
6+
root = tk.Tk()
7+
8+
# set the title
9+
root.title('Banana interest survey')
10+
11+
# set the root window size
12+
root.geometry('640x480+300+300')
13+
root.resizable(False, False)
14+
15+
###########
16+
# Widgets #
17+
###########
18+
19+
# Use a Label to show the title
20+
# 'font' lets us set a font
21+
title = tk.Label(
22+
root,
23+
text='Please take the survey',
24+
font=('Arial 16 bold'),
25+
bg='brown',
26+
fg='#FF0'
27+
)
28+
29+
# Use an Entry to get a string
30+
name_label = tk.Label(root, text='What is your name?')
31+
name_inp = tk.Entry(root)
32+
33+
# Use Checkbutton to get a boolean
34+
eater_inp = tk.Checkbutton(root, text='Check this box if you eat bananas')
35+
36+
# Spinboxes are good for number entry
37+
num_label = tk.Label(root, text='How many bananas do you eat per day?')
38+
num_inp = tk.Spinbox(root, from_=0, increment=1, value=3)
39+
40+
# Listbox is good for choices
41+
42+
color_label = tk.Label(root, text='What is the best color for a banana?')
43+
color_inp = tk.Listbox(root, height=1) # Only show selected item
44+
# add choices
45+
color_choices = (
46+
'Any',
47+
'Green',
48+
'Green-Yellow',
49+
'Yellow',
50+
'Brown spotted',
51+
'Black'
52+
)
53+
for choice in color_choices:
54+
# END is a tkinter constant that means the end of an input
55+
color_inp.insert(tk.END, choice)
56+
57+
58+
# RadioButtons are good for small choices
59+
60+
plantain_label = tk.Label(root, text='Do you eat plantains?')
61+
# Use a Frame to keep widgets together
62+
plantain_frame = tk.Frame(root)
63+
plantain_yes_inp = tk.Radiobutton(plantain_frame, text='Yes')
64+
plantain_no_inp = tk.Radiobutton(plantain_frame, text='Ewww, no!')
65+
66+
# The Text widget is good for long pieces of text
67+
banana_haiku_label = tk.Label(root, text='Write a haiku about bananas')
68+
banana_haiku_inp = tk.Text(root, height=3)
69+
70+
# Buttons are used to trigger actions
71+
72+
submit_btn = tk.Button(root, text='Submit Survey')
73+
74+
# Use a label to display a line of output
75+
# 'anchor' sets where the text is stuck if the label is wider than needed.
76+
# 'justify' determines how multiple lines of text are aligned
77+
output_line = tk.Label(root, text='', anchor='w', justify='left')
78+
79+
80+
#######################
81+
# Geometry Management #
82+
#######################
83+
# Using Grid instead of pack
84+
# Put our widgets on the root window
85+
#title.grid()
86+
# columnspan allows the widget to span multiple columns
87+
title.grid(columnspan=2)
88+
89+
# add name label and input
90+
# Column defaults to 0
91+
name_label.grid(row=1, column=0)
92+
93+
# The grid automatically expands
94+
# when we add a widget to the next row or column
95+
name_inp.grid(row=1, column=1)
96+
97+
# 'sticky' attaches the widget to the named sides,
98+
# so it will expand with the grid
99+
eater_inp.grid(row=2, columnspan=2, sticky='we')
100+
# tk constants can be used instead of strings
101+
num_label.grid(row=3, sticky=tk.W)
102+
num_inp.grid(row=3, column=1, sticky=(tk.W + tk.E))
103+
104+
#padx and pady can still be used to add horizontal or vertical padding
105+
color_label.grid(row=4, columnspan=2, sticky=tk.W, pady=10)
106+
color_inp.grid(row=5, columnspan=2, sticky=tk.W + tk.E, padx=25)
107+
108+
# We can still use pack on the plantain frame.
109+
# pack and grid can be mixed in a layout as long as we don't
110+
# use them in the same frame
111+
plantain_yes_inp.pack(side='left', fill='x', ipadx=10, ipady=5)
112+
plantain_no_inp.pack(side='left', fill='x', ipadx=10, ipady=5)
113+
plantain_label.grid(row=6, columnspan=2, sticky=tk.W)
114+
plantain_frame.grid(row=7, columnspan=2, stick=tk.W)
115+
116+
# Sticky on all sides will allow the widget to fill vertical and horizontal
117+
banana_haiku_label.grid(row=8, sticky=tk.W)
118+
banana_haiku_inp.grid(row=9, columnspan=2, sticky='NSEW')
119+
120+
# Add the button and output
121+
submit_btn.grid(row=99)
122+
output_line.grid(row=100, columnspan=2, sticky='NSEW')
123+
124+
# columnconfigure can be used to set options on the columns of the grid
125+
# 'weight' means that column will be preferred for expansion
126+
root.columnconfigure(1, weight=1)
127+
128+
# rowconfigure works for rows
129+
root.rowconfigure(99, weight=2)
130+
root.rowconfigure(100, weight=1)
131+
132+
#####################
133+
# Add some behavior #
134+
#####################
135+
136+
def on_submit():
137+
"""To be run when the user submits the form"""
138+
139+
# Many widgets use "get" to retrieve contents
140+
name = name_inp.get()
141+
# spinboxes return a str, not a float or int!
142+
number = num_inp.get()
143+
# Listboxes are more involved
144+
selected_idx = color_inp.curselection()
145+
if selected_idx:
146+
color = color_inp.get(selected_idx)
147+
else:
148+
color = ''
149+
# We're going to need some way to get our button values!
150+
# banana_eater = ????
151+
152+
# Text widgets require a range
153+
haiku = banana_haiku_inp.get('1.0', tk.END)
154+
155+
# Update the text in our output
156+
message = (
157+
f'Thanks for taking the survey, {name}.\n'
158+
f'Enjoy your {number} {color} bananas!'
159+
)
160+
output_line.configure(text=message)
161+
print(haiku)
162+
163+
164+
# configure the button to trigger submission
165+
submit_btn.configure(command=on_submit)
166+
167+
###############
168+
# Execute App #
169+
###############
170+
171+
root.mainloop()

0 commit comments

Comments
 (0)