Push My Buttons7:38 with Kenneth Love
Now that we have a grid and a banner, let's make the buttons for starting and stopping our timers. We'll also create our timer label to show time.
The official docs for Tkinter aren't the best in the world but they'll get you started. The documentation from effbot hasn't been updated in about a decade but it's actually still mostly accurate. These are my two main resources for learning Tkinter and preparing this workshop.
Terms and things
Tk() - A Tkinter application. This is what is responsible for the window or application you see on your screen. You'll end up binding most things to this.
mainloop() - The loop that keeps your Tkinter app running. This loop runs forever.
Frame - An invisible box that you can put things in.
Label - A piece of text on the screen.
Button - A button (whodathunk?!)
StringVar - A variable that holds onto a string.
IntVar - A variable that holds onto an int.
trace() - A way to follow the changes and access of a variable.
rowconfigure() - Methods to configure the number and weight of columns and rows.
pack() - Method to insert a widget in the available space.
Okay, so we've built a grid, and we've built a banner, but 0:00 right now that's all we got. 0:03 We've got this logo banner thing, 0:04 and then we've got a grid, not the most exciting thing ever. 0:06 So, we need buttons to start and stop our timer. 0:10 So, let's create a couple of buttons and add them to the bottom of the window. 0:14 I'm gonna do this a little bit backwards. 0:18 I'm gonna say that I'm gonna call self.build_buttons. 0:20 And then I'm gonna come down here and actually write self.build_buttons. 0:23 All right, so, build_buttons. 0:28 All right, so, the first thing I wanna do, because I had these two buttons and 0:32 I wanna make sure that they do what I want them to do and 0:37 appear where I want them to appear. 0:40 I can do this with pack, but reasoning grids let's just keep using grid. 0:42 I'm gonna make a new grid for them to fit into inside the old grid. 0:45 So, I'll make a new frame. 0:49 So, we're gonna say buttons_frame = tkinter.Frame and 0:50 this belongs to the mainframe. 0:55 All right? 1:00 And then we're gonna say the buttons_frame.grid. 1:01 It's in row 2 and it's in column 0. 1:06 And it's sticky on, I mean, again, we really only need east and west. 1:12 But we're gonna do north, south, east, and west, just to do it. 1:18 And then I want this one to be padded as well. 1:23 What's cool is that that actually fits all on one line. 1:27 That's 77 characters, so that's cool. 1:29 So now, let's configure the grid of our buttons frame. 1:33 Now, we only have one row, and that row isn't going to resize. 1:39 So, it's row 0 and weight of 0, so we don't even have to talk about it, but 1:43 let's talk about our columns. 1:47 So column 0 is gonna have a weight of 1, and let's just copy this. 1:48 Column 1 is gonna have a weight of 1. 1:55 Okay, so now, let's build the buttons. 1:58 So we're gonna have a start_button, and we're gonna assign this to self so 2:02 we can get back to it later. 2:06 And it's gonna be tkinkter.Button, not butter. 2:08 And it's gonna belong to the buttons_frame. 2:12 And I want the text on this to be the word Start and that's it. 2:15 Now, we're gonna get these commands later, but 2:21 we don't have to worry about that right now. 2:22 We don't have to assign any commands at the beginning. 2:23 And then, let's make a stop_button. 2:27 And I bet you can guess most of this. 2:32 The text is gonna be Stop. 2:34 Who'd have thunk, right? 2:37 Okay, so now let's assign these things to their grid. 2:39 You know what, I'm gonna. 2:42 Can I make that smaller? 2:44 I guess I can, okay. 2:46 So start_button.grid, I want it to be in row 0 and column 0. 2:48 And I want it to be sticky to both sides. 2:54 And you know what, I want this exact same thing for stop_button. 2:58 The only difference is I want it to be in column 1, not column 0. 3:04 So let's see what this does. 3:09 Let's run it, and bring the window over. 3:11 And there's our two buttons, and the buttons grow with the window. 3:18 That's what that sticky east west gives us. 3:22 So, we can start. We can stop. 3:25 They're not doing anything at this point, and that's fine, but 3:27 that's what we can do. 3:30 Okay, so that's cool. 3:33 Let's start on our timer. 3:34 All right. 3:36 So, we need to build a timer. 3:37 So let's go up here, and we're gonna call self.build_timer. 3:41 Yeah, more or less. 3:49 And then we're gonna come down here and make a new function. 3:50 You know what? Let's do, yeah, we'll do that here. 3:54 def build_timer, all right. 4:00 And what I wanna do in here is I wanna build the label. 4:03 So timer is gonna be tkinter.Label. 4:07 It's gonna belong to the mainframe cuz we're gonna put it into that grid in 4:10 the middle. 4:15 text is gonna just =TIMER for now, and let's give it a nice big font. 4:16 We'll say Helvetica, and we'll make it 36 pixels tall. 4:22 And then, we want the timer to go into its grid. 4:28 We want it to be in row 1, column 0. 4:31 And we want it sticky to all four directions. 4:35 There's a problem, though. 4:39 Right now, okay, let's run this just so you can see what it looks like. 4:40 So there's our timer, and we can resize it, and 4:44 our time stays right in the middle. 4:47 Okay, the problem is though we don't want it to actually say TIMER, right? 4:48 We want there to be a clock. 4:52 So, what we need to do is we need to make a variable that 4:55 we're gonna be able to change. 4:59 So, let's come back up here to the top, and 5:01 we're gonna make a new item right here. 5:03 Now, TkInter has these certain variable types, and they're a little weird for 5:07 working within Python because you're used to being able to just change an attribute. 5:13 Things in Tkinter are a little different. 5:18 You can change attributes on some stuff, on some stuff you can't. 5:20 You have to use this config method. 5:23 Most of the time, you should use the config method. 5:25 And then you pass in kwargs or a dictionary unpacked as kwargs or whatever. 5:27 So anyway, Tkinter has some different variable types. 5:33 There's a string var. 5:36 There's an int var. 5:37 We're gonna use string var for right now because we want it to hold onto a string. 5:38 And this will let us watch the variable later on. 5:42 And whenever the variable changes, we can trigger other stuff to happen, okay? 5:46 So let's make this, we're gonna call it timer_text, and it's gonna be a StringVar. 5:50 Okay, and that's it. 5:58 That's all we gotta do. 5:59 And then come down here and instead of saying TIMER, like this one does. 6:01 We're gonna make it say self.timer_text.get. 6:06 See, we have to use that method. 6:12 We have to use .get instead of timer_text. 6:12 So that's a little bit weird. 6:16 To get to actually counting stuff, right? 6:18 We need a variable that holds on to some time. 6:21 So let's come back up here, and let's make another one, another variable. 6:26 And we'll say self.time_left, and it's an IntVar 6:31 cuz we always have a number of seconds left, and it's always a whole number. 6:37 Believe it or not IntVars hold on to ints, okay? 6:41 Now we could use date, time and be hey, find me a time 25 minutes ahead of now, 6:45 and then count down the time to there. 6:50 That's nowhere near as simple as this. 6:53 I just wanna hold on to a number of seconds, right? 6:56 And just be done with it. 7:01 So, up here, outside of my class, I'm gonna define a constant, DEFAULT_GAP. 7:01 And it's gonna be, let's see there are 60 seconds in a minute, and 7:09 I want 25 minutes, okay? 7:13 So 60 * 25. 7:15 And then here, I've made this time_left and now I'm gonna set it. 7:17 And I'm gonna set it to DEFAULT_GAP. 7:23 Now, the default time for Pymodoro is 25 minutes, and I've just set this thing up. 7:26 So that's cool. 7:32 I don't have to do anything else with this. 7:32 Before we get into the next stuff, let's take a little break. 7:35
You need to sign up for Treehouse in order to download course files.Sign up