ROBERT MALATE: Good afternoon,
this is CS50, and thank you for coming to today's seminar. Today, we are going to cover
GUI with Python's Tkinter. My name is Robert Jomar
Malate and this is Tkinter. So you might be asking, what is Tkinter? Well it's a library in Python
that provides a lightweight GUI, or also known as a
Graphical User Interface. It's quite simple. It's not too complex so it
would be a fun project to do. This is great for
making your apps visual. For example, here, if
you create a program that generates a random password. So let's say, for example, you call
it the Random Password Generator. You would put the number of characters
and then it gives a certain password. However, that's a little bit boring, but
what if you could bring that to life? Tkinter provides that
opportunity here and it's great for making simple
Python apps such as this, where it turns from this from the
command prompt to a Graphical User Interface. Now the objectives for
today's seminar is-- what we're going to cover is one
simple GUI building, which is basically the basics of Tkinter, where we'll
learn how to insert entry fields and labels into our app. And additionally, we
want to insert buttons and we want to display the
results of some action, such as pressing the button. However, what we're not going
to cover is advanced methods, such as including pictures or including
audio or game making, because this requires another Graphical User
Interface built onto Python that is separate from Tkinter. And additionally, we're not going to
cover object-oriented programming. Most of the documentation of Tkinter
is done in object-oriented programming. But what I want to try
to do for you guys today is give you a brief introduction
of how Tkinter works and what you can do with it. So for the setup, Tkinter can't run
on the CS50 ide or any online ide so you're going to need to
install Python onto your computer. You can follow this link here. Go to Python.org/downloads. From there, you can select
Python 3 and download that. And usually Tkinter is automatically
installed in there, but if it's not, what you want to do is put
this in your command line-- sudo pip install tkinter-- and you should be good to go. So after you're done with your
setup, you have a text editor open. Everything is all set. Let's start coding. So Tkinter. The mindset you want
to have for Tkinter is think of it as a stained
glass where you have the frame and inside that frame is
separate pieces of glass. So for example, in this stained
glass, you have the frame over here. However, you can see it's made
up of multiple pieces of glass, such as this black glass here,
this glass for the light saber. You can think of that analogy as a
way to construct your Tkinter GUI app. Over here, you have your window,
which is the frame, and in that frame is going to be separate blocks,
where inside those blocks you can put your labels, your
entry fields, and your buttons. So first, let's create the label. Let's create the window. So I'm going to open up
my text editor and I'm going to save this and
let's call this MyApp1.py. App So what do we want to do? So first, we want to of course
import the Tkinter library. So what we'll do is import Tkinter. And to shorten the phrasing, we'll
just say import Tkinter as tk. Now next up is we want
to create the window. So how do we do that? Well we can declare a variable. Let's just call it Window. And let's set that
window equal to tk.tk. So what this is saying is
that the window variable now has the properties of
all the stuff in Tkinter. Now what we want to do is
actually make that window run but it's kind of weird how Tkinter
works because it's kind of like window is now part of it, so you kind of
have to call it like a function. However, there is a special function
that need to call, so what you would do is put window.mainloop. And what this is saying is
that you declared a window and what main loop does, it runs
everything inside that window. So let's save this. [INAUDIBLE] And there you have it. You have a Tkinter window right here. This is the window you created. So this is essentially
the frame that you want to create to start building your apps. However, there are some
things you notice here. For example, one, there was a
default size of just about a few hundred pixels. And over here, you don't have a title. It just shows tk. The next thing we want to do is
try to add a title to our own. And as you can refer
here to the PowerPoint, tk declares this variable as the frame. Title will input whatever
title you want for the app. And Geometry sets the size in
pixels of what the window will be. So let's go back to our
app and let's code that in. So what we'll do is window.title and
then we can put a phrase in there. And let's say this is called My App. And then we want to set the size
of this window to default size so when the user opens it, it
comes out as an aesthetic size. And let's say we want a square
of about 400 by 400 pixels. And one thing you want to
notice here is that it's between main loop and the
declaration of window. The reason is because
main loop kind of works like a function, where if you
call it at certain places, it's going to call it
but not include stuff. So for example, if window.mainloop
was in line 5 instead of line 10, we would not see the title or
the window would not change to the certain geometry shape you want. So let's save this. Let's close our old GUI
and let's run it again. And as you can see, this time it
came out to a different shape. This time, this is a
window 400 by 400 pixels. And now it has the title called My App. Now we got the frame down but we
want to add the pieces of glass to the stained glass over here. So what we would do is
call certain arguments. We want to give it certain properties,
and among the ones we're going to use today is .label, .button,
.entry, and .text, where each of them take
a certain argument. So what we want to do first is
we're going to create a label, then we're going to create a button, and
then we're going to add an entry field. Now these are not going to do anything. For example, if you press the button,
it's not going to display anything, but what we want to do is just
to try to see how it'll work. So let's go back to our app. And we can do-- now this is the part where you
want to comment your lines of code, mainly because you want to just keep
it organized because it could get messy a little bit quickly. So first, let's create the prompt. So let's call this Label and
let's call the prompt Title. And what we'll do is tk.label. And we can pass in text into it. And let's say, "Hello world, welcome
to CS50 and welcome to my app." App. Now the thing is, what you just did
is you gave the piece of stained glass but you don't know where that piece of
stained glass is actually going to go. So what you want to do is you need
to declare, where is it going to go? So what you'll do is call Title
because Title is the label. You want to place it on the
window, so we'll do title.grid. And what we want to do is
specify the column or row, but automatically, what Tkinter
does, it sets it to the row 0, 0. So if you were to refer back
to the coordinates here, this box here would be 0, 0. This would be 0, 1, 0, 2,
1, 0, 1, 1, 1, 2, and so on. So now that we created our
label, let's go test this out. And as you can see here, now
we have the window, the frame, we have the title, a
certain geometry, and now we added our label that says,
"Hello world, welcome to CS50 and welcome to my app." Now let's add a little
more functionality. Let's add entry fields
and let's add a button. So let's call this Button 1. And what we'll do is tk.button. And we want to give it some
text, so maybe let's say-- let's call this button to prompt
the user to say "Click me." And as I've said before, we need
to place this button somewhere and we want to place it under,
so we'll do button1.grid. Now here's the point I
would like to remind you, that since the code is
read from top to bottom and the way the grid is displayed
is from 0, 0, 0, 1, 0, 2, it'll read chronologically. So since this appears first, this
will be in 0, 0, this will be in 0, 1. But if we were to switch
it around-- for example, if you were to put the
button first, the button's going to be the first to appear
in the window, then the next below that is the prompt. So we want to specify it. Let's say column equals
0 and row will equal 1. And over here, we'll do the same thing. We'll specify column 0
but row will equal 1. And as you can see here,
now we added the button. Let's add the entry field next. Let's call this Entry Field 1. And we'll do tk.entry. Now the thing with Entry field, it's
kind of like an HTML form or a Submit form where there's a blank box and then
you type whatever you want inside it. There are certain arguments that insert
it but we'll cover more on that later. So what we'll do is, now we
declared the entry field, we want to place it on the grid,
so we'll do entryfield1.grid. We want to put this entry
field right below our button. And as you can see here, now
we have our entry field inside. So that's pretty much it for
the setup of the Tkinter. Now we want to try to
build it up from there. So, ahead of time, I wrote some
programs that display this, so let's refer to this one. App2.py. So as you can see here,
this is the same thing. We're declaring a window. The title of that window is
going to be My Awesome App. The geometry of that window is going
to be a square of 300 by 300 pixels. Here, we're going to have a
label that says, "This is CS50. Welcome to my awesome app." We're going to have an entry field
there, a button, and a text field. This was the app we created. Now we want to include-- now this is for you guys to see
how it looks like and how it works. But this is kind of bland. A little bit boring. So what if you say that you want
to change the font of this label or you want to make this button red. So let's say we want to change the
font of this to Times New Roman, maybe size 20 font, and maybe let's
make the button red so the user will be more inclined to push it. Well I wrote code ahead
of time for this one. This is the same exact one except
it takes in extra arguments. So first, you can notice here that
label has additional arguments. For example, we still have the text. However, now we have the font. And what this font is specifying
is that will be Times New Roman and it will be size 20 font. Now this is not the
only arguments for it. There are documentation on these
but we'll refer to them later. And then also you notice on the
button that it has the text "Click me" but also has bg, or
background, as color red. So let's try running this app. And as you can see here,
now we have some new-- our app looks a lot more creative
and a lot more different. This time, it has Times New Roman
font and the button is now red. So as you can see, there
are a lot of arguments that you can pass on to these, and you
can find these arguments at fbot.org. And here you can see a lot of new
resources of the documentation they include for Tkinter. Now before we begin on making an app,
let's start with the general steps. So step number zero is you want
to plan out a layout for your app. As you can see here, we
need to treat Tkinter as a frame, where we have the frame
and we have the pieces of stained glass and we want to put those
stained glass in certain places. That's why we want to lay out our app. So for example, let's say we
want to create an app where it displays a greeting,
it takes in your name, and it displays, hello, your name. So what we'll do is
we'll add a label here, another label here that prompts the user
to ask them for their name, an entry field here, a button,
and below that button will be a text field that
will pop out that will say the user's name and a greeting. So we planned out our app. Next is we want to create
the window of our app. So let's create a new app and
we can call this NewApp.py. And let's start by creating the window. So first, we want to import the
Tkinter library as tk, and remember, tk is just a shorter
way of saying Tkinter because normally we would have to
put Tkinter.label or Tkinter.button. But using tk, we can
use shorter characters. Now we want to declare the window,
so we'll do window will equal tk.tk. And we want to add the title
and geometry of the window, so window will equal window.geometry. Let's make it 400 by 400 pixels. And next what we want
to do is add the title, window.title, and let's
call this Greetings. Greetings blank. And of course, we don't want
to forget the crucial process. For this to actually exist or for
the window to actually pop out, we're going to need to put the main
loop, so we'll do window.mainloop. And as you can notice
from our previous programs where the main loop is
always at the bottom, we want to push this to the
bottom whenever we add new things or add new entry fields or buttons or
else it won't display on the screen. And one more thing I'd like
to note is that you always want to compile to see where your errors
are so this will make debugging easier. So by taking this step by step, starting
with the frame, then the buttons, and then the function that
will run from those buttons, you'll be able to debug
quicker and be able to spot any problems that occur in your code. So first, let's compile this. We'll run Python New App. As you can see, we got the
window and now we got the title. Now time to add the label
prompt, so we'll add label here and we'll call this
Beginning Label, or Label 1. And let's make it say
"Welcome to my app." And of course we want to place this
on the window, so what we'll do is label1.grid. And we want to specify this, so
originally in our planning stage, we said we want this
welcome greeting to be in the 0, 0 position or the
top leftmost corner of the map. So we'll put this in column 0, row 0. And now we want to add
the next label that will ask the user for what is their name. So we'll create another label. Let's call it Label 2. And let's ask them, "What is your name?" And we are going to
place it on our grid. Now we want to compile
this code to make sure that it is placing at the
appropriate places we want the labels to appear in our window. And we now do have a bug. Now I think I just spotted
the bug and the main reason is because we misspelled. So be very careful of your spelling. And one thing that Tkinter
doesn't really take note of is, for example, if I
just put cat here, cat is not really a function or an
argument but it will accept it. So this is really important for
you to check the documentation to look for legitimate arguments that
you could pass on to the function. Let's run this again. And there we have it. We have the first label at
the very top leftmost corner position that says, "Welcome to
my app," and the next label that says, "What is your name?" right below it. Now let's add the entry field
where the entry field will go right next to your name so the
user knows-- so it will look prettier and it will look a
little more intuitive. So what we want to do
is add the entry fields. And let's call this Entry 1. And we'll do tk.entry. Now remember, again, we're
not accepting any arguments here because we want the
user to put in something. So we'll just leave it blank. And we want to place that right
beside the second label of "What is your name?" So it will belong in the same
row but go to a different column. So we'll do entry1.grid,
column 1, row 1. So it seems working fine. The stuff we wanted is
placed in the right places. And for over here, we
can input characters. We can even input numbers. Now let's add the button. So we'll just call this Button 1. And of course, again,
we want to place it. So let's say we want to place
it right below the name prompt. So "What is your name?",
and right below that, we want to put the button over there. So it will belong to the 0th
column and in the second row. So we'll do button1.grid,
column 0 and row 2. And in that button, we want to
have a prompt phrase, so let's make the button say, "Click me." Now we have the general
components created of our app now. We have the labels, we have the entry
fields, and we have the buttons. But the thing is, for
example, if I were to just put my name, Robert, it's not
actually going to do anything because the button is just a button. It just exists right there. This is the part where we're
going to need to include a command argument or a function. So we're going to close this
window and go back to our app. And because of the way the programs are
read in a computer from top to bottom, we're going to need to put
the function above the button, because if the button is the one that's
going to be calling the function, we want to put the function above it. So we'll define our functions here. And let's call this first
function the Phrase Generator, where it will return your name
and a phrase put together. And to make this a
little more fun, let's make the phrase generate random
phrases that we manually input. So for example, it could say
"hello," "what's up," "aloha." So first, we want to also
import the random module, and let's start defining the functions. So Phrase Generator phrase. First, we need to create
the list of phrases that the computer will
pick from, so what we'll do is we'll create a list called
Phrases and we'll put it as a list. And let's say we'll
pass in three phrases. We'll say "hello," "what's up,"-- "hello," "what's up," and "aloha." And from my home island,
we'll also include a phrase that's also "hi" called [INAUDIBLE]. Now what we want to do is get
that phrase from the entry field. So this is the function
we're going to call, is .get. So we want to store
this inside a function. Let's call this Name. And we're going to
convert this to a string. And what we want to get
is from the entry field, so we're going to go
to Entry Field 1 and we want to get whatever is stored inside
it and store it in the variable name. So we'll do entry1.get. Now we already got the components. We got the list of phrases. We got the name. Now let's return this. So we're going to do some
string concatenation here. We're going to call phrases. And we're going to randomly
select one of these phrases, so we'll do random.randint
from 0 to 3 plus name. So essentially what this
Phrase Generator is doing is it has a list of phrases and you're
getting the name from the entry field and you're concatenating them. So for example, for my name Robert,
it'll say "Hello, Robert," "What's up, Robert," "Aloha, Robert,"
or ""[INAUDIBLE],, Robert." And any of those will be random. Now the key thing to
focus on here is not the fact about the string
concatenation or the random but this is just one of the things
that you could do with Python-- with Python's Tkinter. So now we created the Phrase
Generator, but the thing is, it just returns the phrase. If we just press the
button-- so for example, if we were just to compile this-- and one more thing I forgot to add,
we also want to add the command. What command does is give the button
the ability to call any function. So since our function is called Phrase
Generator, we'll leave it there. Now we're going to compile this. So for instance, if I put
"Robert," it does nothing. The main reason is because-- OK, so it did return the phrase, and
as you can see here from the command terminal, there was no errors. But it had nowhere to
return that phrase to. So what we want to do
is call the last piece of the puzzle of our stained
glass of our app, which will be the text field, which will
say the greeting and the user's name. So let's close our app here. Now let's define another function. Now what this function will do is it'll
take the Phrase Generator from Phrase Generator and return an output-- a text field where the user can input. Similar to the entry field
but just a lot bigger and can resize and where the
user can change the inputs and copy and paste the inputs. So let's define this as Phrase Display,
where I'll take in no arguments, and let's call-- now remember that Phrase Display has
no idea of what Phrase Generator did, so we want to actually get the
greeting from Phrase Generator and make it display in Phrase Display. So what we'll do is we'll store
it in the variable Greeting and we're going to
call Phrase Generator. And what we're going to do next is
we're going to create the text field. So this is going to be a little more
cryptic than usual but bear with me. This is the part where we're going
to see our code come to life. So what we're going to do is greeting. We're going to call this
GreetingDisplaytk.text. And what this master window is saying is
that it's putting it inside the window. And the thing is, it doesn't have
a specified height and size yet, so it could appear any dimensions. Usually it appears small. So we want to specify this. So let's say we'll give it a
height of 10 and width of 30. And as before, we want to
actually place this onto our grid, so we'll call this greetingdisplay.grid. And we want this to display
right below our button so it can be nice for the user,
after they press this button, they see their greeting. So what we'll do is look
for the button and we'll put it in the same column
but the row beneath it. Now the thing is, we're
not yet done here. So we did place the
greeting, but the thing is, how do we actually insert
the greeting into the text field? So this is what we want to do. We'll do greetingdisplay.insert because
Greeting Display is the text field and what we want to insert
inside it is the greeting. So we'll do a little cryptic tk.n
and we want to put in the greeting. Now let's try compiling this
and running this program. I'll input my name. It still does nothing. So if we look back at
our code, when we press the button, the function or the command
we assigned it was Phrase Generator. However, Phrase Generator
just returns the phrases, but when it returns the phrases,
it doesn't put it anywhere. It's actually Phrase
Display that returns it. So what do we want to do is
change the command from-- instead of Phrase Generator,
we want to put Phrase Display. Let's close our app. Let's compile it and run it again. Now we got our app. Big moment of truth. And as you can see here, it's a
complete app, where we have our labels, we have our names, it took my
name, I press "Click me," it said, "[INAUDIBLE], Robert." We can press again
because this is random, because every time we
press the button, it calls Phrase Display and Phrase
Display calls Phrase Generator. And remember that Phrase Generator
generates random greetings every time, so what you can do is just
press the button again. It says "Aloha." Press it again. "[INAUDIBLE]." "Aloha." "What's up." Can we get a "Hello?" Yep, we got a "hello." Now we're back to "what's up." So let's play around
with this a little more. So just to prove, let's say,
what if my name was a number? Let's say it was 3.1415. It's saying, "Hello, pi," or
whatever digits of pi you use. Now we skip a lot of steps over here
but let's just recap what we just did. One, we planned the
layout of our app, where we wanted our app to have two labels-- one in the 0, 0 position,
one in the 0, 1 position-- an entry field right next to
the label in the 0, 1 position. Actually, let's refer to this. So what did we just do? So first, we planned
the layout of our app. So we said that we wanted
this to be in the 0, 0 position, or the leftmost
corner, and right below that, we want to have a label
that says, "What is your name?" And right beside that label, we
want to have an entry field where the user can put in any entries. And right below those things,
we want to put a button. And after we click that button,
we want a text field to display. So we planned the layout of our app. Next step, what we did was
create the window for our app. So this occurs in lines here, where
we declared the window, tk.tk, we declared the title of the window-- and as you can see here,
that's greetings blank. It says "greetings blank" here. And then we also set the geometry. Now just keep in mind
that the geometry is not set-- you can resize it all you want--
but this is the default geometry when the code first runs. And of course, we included the main
loop in order to make this all appear. So we created the window for the app. Next what we did is declared the size
and placed the labels, buttons, entry fields on the window. And we used the ideas
of grids to place them. So as you can see over here and back
in our code, we have a label that says, "Welcome to my app." It's in column 0, row 0
and appears so over there. And right below that, the row below
it, it asks, "What is your name?" And the label also does display that. Entry fields, what we did is put
it right beside the label that asks, "What is your name?" And then below that entry
field, we included a button, and what that button will do,
it'll say the words, "Click me," and when you click it,
you run a command-- you will run the
function, Phrase Display. So we did steps two and three
where we placed the labels. Next, we want to connect the buttons
and entry fields to one another through functions. Now this was a critical step
in trying to connect my name and put it inside the entry
field, so let's reflect on what we did back there. So let's say the name was pi. Entry 1. What is stored in Entry
1 is the string, pi. So let's refer back to
our Phrase Generator. What Phrase Generator does,
it takes a string of phrases. And this is the critical
part, entry1.get. What it is saying is that, hey,
Python, go to the Entry 1 field, pull whatever's in there and put
it in this variable called Name. And then to make it a little
fancy, we randomized the greeting so we can get different ones
every time we press the button. And we did some string concatenation. Now, after that, what we
did was Phrase Display, where we're going to store that
concatenated string of a greeting. If it was, "Hello, pi,"
it'll be stored in Greeting. Next is the other critical step
where we actually connected the text. So this is where we declared
the text field to appear, and as you can see here, it's column
0, row 3, right where we want it. It's right below the button, because
keep in mind that the button is row 2. Now the text field is row 3. And next what we did is we
took that greeting and we want to insert it into that text field. So what we did is
greetingdisplay.insert, tk n, and passed in the Greeting variable. So if we run this again,
we get our complete app. Now Tkinter is not just limited to
this and there are a lot more resources available out there. CleverProgrammer.com
Programmer is one that I would recommend to try to search up
more functionality for Tkinter but also just to learn a little bit more Python. And also next is fbot.org, where this is
the most documented place of Tkinter-- not every single variable of
Tkinter is documented here but this is the best one
I've found that doesn't deal with object-oriented programming,
because as one of my research says before that, Tkinter
has not been well documented but this one will be the best place
where you can to find the resources you need for Tkinter. So overall what I wanted to
do for you guys for doing GUI Tkinter is not try to create an app
that simply just generates your name, but I want to give you
a tool that uses it. And I believe that Python's
Tkinter is one way of doing it. I can't wait to see what
you guys will do with it and I hope you have fun with it. Thank you.