WEBVTT 1 00:00:01.867 --> 00:00:03.128 So in the last few videos, 2 00:00:03.128 --> 00:00:06.770 we've looked at the *args and **kwargs parameters 3 00:00:06.770 --> 00:00:09.190 and how we can pass on arguments that we don't need 4 00:00:09.190 --> 00:00:11.723 to handle or in fact don't even know about. 5 00:00:11.723 --> 00:00:14.250 So now it's time to create our own listbox class 6 00:00:14.250 --> 00:00:16.588 that includes its own scrollbar. 7 00:00:16.588 --> 00:00:18.480 Now if we had to start this from scratch, 8 00:00:18.480 --> 00:00:21.208 frankly, it would be a mammoth undertaking. 9 00:00:21.208 --> 00:00:23.268 We'd have to learn another language to start with, 10 00:00:23.268 --> 00:00:25.285 TCL, which is prounounced tickle, 11 00:00:25.285 --> 00:00:28.547 which is what the Python TKinter library uses 12 00:00:28.547 --> 00:00:30.416 to produce all its GUI elements. 13 00:00:30.416 --> 00:00:33.898 But fortunately, we already have a working listbox class 14 00:00:33.898 --> 00:00:37.071 and we can inherit most of the behaviour from that. 15 00:00:37.071 --> 00:00:40.282 So back in jukebox.py, I'm gonna open that up again. 16 00:00:40.282 --> 00:00:42.797 We're going to start some work on that. 17 00:00:42.797 --> 00:00:44.986 We're gonna create a scrollable listbox class 18 00:00:44.986 --> 00:00:48.536 and I'm gonna call that, unoriginally, scrollbox. 19 00:00:48.536 --> 00:00:50.636 So I'm gonna go start this at the top of the file 20 00:00:50.636 --> 00:00:55.204 and it's gonna be after the connect, the SQL connect. 21 00:00:55.204 --> 00:00:57.288 And we'll start this on line 10. 22 00:00:57.288 --> 00:01:00.705 So we're gonna start with class scrollbox 23 00:01:01.991 --> 00:01:04.074 and it's tkinter.listbox. 24 00:01:08.784 --> 00:01:10.451 And again, you have to have those two spaces there 25 00:01:10.451 --> 00:01:13.614 between line seven and the start of the class. 26 00:01:13.614 --> 00:01:16.513 And now we wanna define the init method. 27 00:01:16.513 --> 00:01:19.221 So we're gonna do a def underscore underscore 28 00:01:19.221 --> 00:01:21.616 init underscore underscore, and then we're going 29 00:01:21.616 --> 00:01:24.981 to do parentheses, self comes up automatically, 30 00:01:24.981 --> 00:01:29.064 comma, space, window, comma, space, and **kwargs. 31 00:01:32.645 --> 00:01:35.431 And I'm gonna put a note in here for Python 2 users. 32 00:01:35.431 --> 00:01:37.190 So, and I'm gonna comment that out. 33 00:01:37.190 --> 00:01:40.607 And that would be tkinter dot listbox dot 34 00:01:42.380 --> 00:01:46.376 underscore underscore init underscore underscore self 35 00:01:46.376 --> 00:01:49.709 comma space window comma space **kwargs. 36 00:01:53.372 --> 00:01:55.377 So the syntax is gonna be slightly different again 37 00:01:55.377 --> 00:01:57.210 if you're in Python 2. 38 00:02:01.057 --> 00:02:03.201 But in our case, now we're going to, 39 00:02:03.201 --> 00:02:06.598 after that definition, to a super parentheses dot 40 00:02:06.598 --> 00:02:10.125 underscore underscore init, and then we're going to 41 00:02:10.125 --> 00:02:14.292 pass as arguments window comma space, then **kwargs. 42 00:02:17.452 --> 00:02:20.337 And press enter, then a separate line there. 43 00:02:20.337 --> 00:02:24.337 And we're going to do self.scrollbar is equal to 44 00:02:26.961 --> 00:02:31.128 tkinter.scrollbar parentheses window comma space orient 45 00:02:34.951 --> 00:02:37.868 equals tkinter.VERTICAL comma space 46 00:02:40.473 --> 00:02:42.640 command equals self.yview. 47 00:02:47.186 --> 00:02:49.938 And it's just a parentheses, there's no method call there. 48 00:02:49.938 --> 00:02:51.679 So we're just using the right parentheses 49 00:02:51.679 --> 00:02:53.454 to close off the line, 50 00:02:53.454 --> 00:02:54.504 So what I've done there, you can see 51 00:02:54.504 --> 00:02:55.484 it's pretty straightforward. 52 00:02:55.484 --> 00:02:58.904 We started off by overwriting the init method 53 00:02:58.904 --> 00:03:00.770 to add a scrollbar field after calling 54 00:03:00.770 --> 00:03:02.231 the super.init method. 55 00:03:02.231 --> 00:03:04.484 So super and then there's the creation 56 00:03:04.484 --> 00:03:05.874 of the scrollbar field. 57 00:03:05.874 --> 00:03:07.218 And again, the comment of that code 58 00:03:07.218 --> 00:03:11.239 is for Python 2 users, that's the way to init a listbox, 59 00:03:11.239 --> 00:03:14.726 as that would be done with Python 2's old-style classes. 60 00:03:14.726 --> 00:03:16.411 All right, so now that we've done that, 61 00:03:16.411 --> 00:03:19.856 we've defined our base class, we need to change 62 00:03:19.856 --> 00:03:22.264 our listbox types to scrollbox. 63 00:03:22.264 --> 00:03:24.608 So I come down here and we're gonna start 64 00:03:24.608 --> 00:03:26.296 with the artist listbox. 65 00:03:26.296 --> 00:03:28.956 At the moment, we've got tkinter.listbox. 66 00:03:28.956 --> 00:03:32.789 Let's change artistList instead to be equal to 67 00:03:34.710 --> 00:03:38.877 scrollbox and we'll pass the argument as mainWindow. 68 00:03:40.079 --> 00:03:42.520 Then we need to come down and do the same for albums. 69 00:03:42.520 --> 00:03:44.942 And albums we've done here, albumsList here. 70 00:03:44.942 --> 00:03:47.658 Instead of tkinter.listbox, we're going to 71 00:03:47.658 --> 00:03:49.783 make that scrollbox. 72 00:03:49.783 --> 00:03:54.248 Scrollbox and the arguments there is still mainWindow 73 00:03:54.248 --> 00:03:57.862 and listvariable equals albumLV, nothing's changed there. 74 00:03:57.862 --> 00:03:59.833 And then we also need to come down 75 00:03:59.833 --> 00:04:02.944 and do the same for songList. 76 00:04:02.944 --> 00:04:06.081 So that's the songList here, tkinter.listbox. 77 00:04:06.081 --> 00:04:09.414 We're changing that to be our scrollbox. 78 00:04:11.220 --> 00:04:14.229 And the arguments are still mainWindow and listvariable 79 00:04:14.229 --> 00:04:16.291 will equal songLV. 80 00:04:16.291 --> 00:04:17.708 So if we run this 81 00:04:21.300 --> 00:04:24.425 you can see that we've now got our scrollbox objects 82 00:04:24.425 --> 00:04:27.408 created instead of basic listboxes. 83 00:04:27.408 --> 00:04:29.484 And you can see, in fact, the scrollbar's there now. 84 00:04:29.484 --> 00:04:31.738 We can actually use it to scroll up and down. 85 00:04:31.738 --> 00:04:34.453 But essentially, the scrollbox doesn't add anything yet. 86 00:04:34.453 --> 00:04:37.882 But it is a good idea to test your subclasses frequently 87 00:04:37.882 --> 00:04:39.320 when developing them to make sure 88 00:04:39.320 --> 00:04:41.283 that the programme runs without any errors. 89 00:04:41.283 --> 00:04:43.699 And if it does error out, you'll know exactly 90 00:04:43.699 --> 00:04:45.745 where you were before, and it won't take you 91 00:04:45.745 --> 00:04:48.080 hopefully that long to figure out what's changed 92 00:04:48.080 --> 00:04:50.186 since the last time it was working. 93 00:04:50.186 --> 00:04:52.286 But in any event, now that we can replace 94 00:04:52.286 --> 00:04:56.060 the TKlist box class with our scrollbox subclass, 95 00:04:56.060 --> 00:04:58.799 we can start to add that extra functionality. 96 00:04:58.799 --> 00:05:00.632 So we close that down. 97 00:05:01.973 --> 00:05:05.688 And with our calls, we're passing on any keyword arguments 98 00:05:05.688 --> 00:05:07.914 to the listbox init method. 99 00:05:07.914 --> 00:05:10.318 So if we create one of our own scrollbox objects 100 00:05:10.318 --> 00:05:12.078 with a different background, for example, 101 00:05:12.078 --> 00:05:14.110 that would actually work fine. 102 00:05:14.110 --> 00:05:15.344 And just to show you what I mean by that, 103 00:05:15.344 --> 00:05:17.653 we can go back up to artist, the artist listbox 104 00:05:17.653 --> 00:05:19.902 here on line 38 and we could add 105 00:05:19.902 --> 00:05:24.069 an additional argument there, so background equals 106 00:05:25.086 --> 00:05:29.253 blue and if we run this, we get a lovely blue background 107 00:05:30.897 --> 00:05:33.147 from our artists scrollbox. 108 00:05:34.455 --> 00:05:37.048 Or listbox, to be more technically correct. 109 00:05:37.048 --> 00:05:38.069 So in other words, we don't have to worry 110 00:05:38.069 --> 00:05:40.314 about dealing with any options that the users 111 00:05:40.314 --> 00:05:42.122 of our scrollbox decide they want. 112 00:05:42.122 --> 00:05:46.419 We're just passing the lot on in the kwargs argument. 113 00:05:46.419 --> 00:05:48.070 Now black text though on the background's starting 114 00:05:48.070 --> 00:05:51.538 to look awful, so I'm going to actually undo that change 115 00:05:51.538 --> 00:05:54.288 and again, what I mean by that is 116 00:05:56.511 --> 00:05:58.219 it's not really a good look there with that blue, 117 00:05:58.219 --> 00:06:03.124 so I'm going to again just get rid of that blue background 118 00:06:03.124 --> 00:06:04.490 by just undoing it. 119 00:06:04.490 --> 00:06:07.015 I'm gonna go back to how it was now on line 38, 120 00:06:07.015 --> 00:06:08.059 but keep in mind if you do want 121 00:06:08.059 --> 00:06:10.575 to give your scrollboxes different colours and fonts 122 00:06:10.575 --> 00:06:14.062 that's fully supported via the kwargs argument now. 123 00:06:14.062 --> 00:06:16.382 But in our case, we've just created our own subclass 124 00:06:16.382 --> 00:06:19.304 of listbox that we can add extra functionality to, 125 00:06:19.304 --> 00:06:20.867 so let's do as the name suggests 126 00:06:20.867 --> 00:06:22.891 and actually add a scrollbar. 127 00:06:22.891 --> 00:06:24.863 So the time to do that is when our scrollbox 128 00:06:24.863 --> 00:06:27.397 is added to the layout manager. 129 00:06:27.397 --> 00:06:29.984 Now we're only going to support the grid manager 130 00:06:29.984 --> 00:06:31.191 and so consequently to do this 131 00:06:31.191 --> 00:06:33.616 we're going to override the grid method. 132 00:06:33.616 --> 00:06:36.460 So let's go back up to our class definition. 133 00:06:36.460 --> 00:06:38.241 And we're gonna add the code here. 134 00:06:38.241 --> 00:06:41.556 And we'll start the code here on line 18 135 00:06:41.556 --> 00:06:44.767 and we'll define that or override that grid method. 136 00:06:44.767 --> 00:06:49.587 So that's gonna be def grid, self is the first parameter, 137 00:06:49.587 --> 00:06:53.420 then it's comma space row, comma space column, 138 00:06:54.939 --> 00:06:59.106 comma space sticky is equal to nsw in single quotes, 139 00:07:00.569 --> 00:07:03.684 comma space rowspan is equal to one, 140 00:07:03.684 --> 00:07:07.346 comma space columnspan is equal to one, 141 00:07:07.346 --> 00:07:10.179 comma space, you guess it, kwargs. 142 00:07:12.776 --> 00:07:15.558 And Python 2 users, the equivalent would be 143 00:07:15.558 --> 00:07:18.808 tkinter.listbox.grid and I'll just type 144 00:07:21.934 --> 00:07:23.684 this in real quickly. 145 00:07:38.557 --> 00:07:41.321 Again, if you're a Python 2 user. 146 00:07:41.321 --> 00:07:44.031 But in our case, we're now gonna do a super method 147 00:07:44.031 --> 00:07:45.364 called dot grid. 148 00:07:46.814 --> 00:07:51.104 And it's gonna be row equals row, comma space column 149 00:07:51.104 --> 00:07:55.104 equals column, comma space sticky equals sticky, 150 00:07:58.051 --> 00:08:02.218 comma space rowspan equals rowspan, comma space columnspan 151 00:08:05.467 --> 00:08:08.800 equals columnspan, comma space, and yes, 152 00:08:09.830 --> 00:08:12.163 KWargs on the end, **kwargs. 153 00:08:14.492 --> 00:08:15.626 So that's the super call. 154 00:08:15.626 --> 00:08:19.209 Then we also wanna do a self.scrollbar.grid 155 00:08:21.454 --> 00:08:26.244 row equals row, comma space column equals column, 156 00:08:26.244 --> 00:08:30.368 comma space sticky equals in single quotes nse, 157 00:08:30.368 --> 00:08:33.701 comma space, and rowspan equals rowspan. 158 00:08:35.474 --> 00:08:38.771 And then we wanna do a self left to right square brackets 159 00:08:38.771 --> 00:08:41.688 and in single quotes yscrollcommand 160 00:08:44.223 --> 00:08:47.473 and that's equal to self.scrollbar.set. 161 00:08:49.302 --> 00:08:51.257 All right, so the first line in the method 162 00:08:51.257 --> 00:08:54.107 is calling the super, the super class's grid method 163 00:08:54.107 --> 00:08:55.622 and we're passing on any options that 164 00:08:55.622 --> 00:08:57.467 we don't wanna use in kwargs. 165 00:08:57.467 --> 00:08:59.199 And once again in the line above that 166 00:08:59.199 --> 00:09:01.989 I've included the method you'd use for Python 2, 167 00:09:01.989 --> 00:09:03.721 its old-style classes. 168 00:09:03.721 --> 00:09:05.959 Now note that all the options we have included 169 00:09:05.959 --> 00:09:09.315 in our definition of this method won't be present in kwargs. 170 00:09:09.315 --> 00:09:11.862 As we saw in the last video, any additional options 171 00:09:11.862 --> 00:09:14.479 that the calling code uses will just be passed on 172 00:09:14.479 --> 00:09:16.717 to the super classes grid method. 173 00:09:16.717 --> 00:09:20.313 So the remaining code is two lines starting on line 21. 174 00:09:20.313 --> 00:09:22.434 This is just the code we used further down the programme 175 00:09:22.434 --> 00:09:23.998 to display the scrollbar. 176 00:09:23.998 --> 00:09:27.093 Now we use the scrollbar classes grid method 177 00:09:27.093 --> 00:09:28.869 just like we did in the main code. 178 00:09:28.869 --> 00:09:30.917 So we know the row and column because they were 179 00:09:30.917 --> 00:09:33.786 passed into a grid method, so we can put the scrollbar 180 00:09:33.786 --> 00:09:35.895 at the same cell on the grid. 181 00:09:35.895 --> 00:09:38.404 So consequently now, our scrollbar should display 182 00:09:38.404 --> 00:09:40.339 its own scrollbar and we can remove 183 00:09:40.339 --> 00:09:43.095 the scrollbar code from the main programme. 184 00:09:43.095 --> 00:09:44.551 So if we come down to the main code 185 00:09:44.551 --> 00:09:47.335 and I'll just put that up on the screen. 186 00:09:47.335 --> 00:09:51.085 So after the code on line 46, we can actually 187 00:09:52.356 --> 00:09:54.165 delete these four lines. 188 00:09:54.165 --> 00:09:55.896 The blink line and then these other three lines here, 189 00:09:55.896 --> 00:09:59.783 the tkinter.scrollbar, the grid and the yscroll command, 190 00:09:59.783 --> 00:10:01.598 because we're implementing those in our class. 191 00:10:01.598 --> 00:10:04.016 I'm deleting that and likewise for album, 192 00:10:04.016 --> 00:10:05.159 if we go down, we're going to delete 193 00:10:05.159 --> 00:10:06.674 those four lines as well. 194 00:10:06.674 --> 00:10:09.062 One, two, three, four, for the same reason, 195 00:10:09.062 --> 00:10:11.714 we've got it in our own class. 196 00:10:11.714 --> 00:10:13.616 All right, so that now looks a lot neater 197 00:10:13.616 --> 00:10:14.786 and we haven't got the code that 198 00:10:14.786 --> 00:10:18.713 we copy and pasted to create the scrollbars. 199 00:10:18.713 --> 00:10:23.496 Let's just test the programme to make sure that it does work. 200 00:10:23.496 --> 00:10:27.455 And I'm gonna have a look at the output. 201 00:10:27.455 --> 00:10:30.092 And it actually looks like we have got a problem here. 202 00:10:30.092 --> 00:10:32.555 You can see, we've got a scrollbar to the left here. 203 00:10:32.555 --> 00:10:37.327 We've got one for albums, but we haven't got one for songs. 204 00:10:37.327 --> 00:10:39.095 And I click on now what I've done there. 205 00:10:39.095 --> 00:10:41.304 You can see the scrollbar that appears 206 00:10:41.304 --> 00:10:44.346 to be for artists actually works for albums. 207 00:10:44.346 --> 00:10:47.848 So I think I've got my sticky statement wrong. 208 00:10:47.848 --> 00:10:50.492 And we go back and have a look. 209 00:10:50.492 --> 00:10:51.906 So I've got sticky equals nsw, 210 00:10:51.906 --> 00:10:53.936 so we're actually trying to stick the scrollbar 211 00:10:53.936 --> 00:10:56.775 to the west, to the left in other words, 212 00:10:56.775 --> 00:10:59.246 and it should be east, because we want it 213 00:10:59.246 --> 00:11:02.151 to appear to the rightmost part of our listbox. 214 00:11:02.151 --> 00:11:04.475 So I would suspect that's probably the error. 215 00:11:04.475 --> 00:11:06.533 So let's just fix that, or run that rather, 216 00:11:06.533 --> 00:11:08.366 and see that it works. 217 00:11:09.571 --> 00:11:10.773 All right, that looks better to me. 218 00:11:10.773 --> 00:11:12.485 We've got our scrollbar here that's disabled 219 00:11:12.485 --> 00:11:14.372 because we haven't got any entries. 220 00:11:14.372 --> 00:11:16.510 And for songs, we can see there's now a scrollbar. 221 00:11:16.510 --> 00:11:19.142 And we've got the scrollbar that actually works 222 00:11:19.142 --> 00:11:21.637 for albums now, that's much better. 223 00:11:21.637 --> 00:11:23.322 All right, so you can see that they're all working now 224 00:11:23.322 --> 00:11:24.904 and that's good. 225 00:11:24.904 --> 00:11:27.968 Now we could improve it slightly by putting 226 00:11:27.968 --> 00:11:30.377 a check in to the grid method. 227 00:11:30.377 --> 00:11:32.021 At the moment, the scrollbar can only appear 228 00:11:32.021 --> 00:11:34.146 on the right of the listbox. 229 00:11:34.146 --> 00:11:35.924 That's assuming you've got the right sticky commands 230 00:11:35.924 --> 00:11:37.795 pointing, going to the right. 231 00:11:37.795 --> 00:11:40.434 So we could test the value of a sticky that's passed in 232 00:11:40.434 --> 00:11:43.473 and then if it specifies east instead of west, 233 00:11:43.473 --> 00:11:45.903 make the scrollbar sticky to the west. 234 00:11:45.903 --> 00:11:47.732 So I'm not gonna do that now, but give it a go 235 00:11:47.732 --> 00:11:49.252 if that's something you wanna do. 236 00:11:49.252 --> 00:11:52.779 All right, so I'm gonna close that down. 237 00:11:52.779 --> 00:11:55.783 And at this point, we've successfully subclassed 238 00:11:55.783 --> 00:11:59.303 the tkinter listbox to create our own scrollbox, 239 00:11:59.303 --> 00:12:01.882 as well as provide it some additional functionality. 240 00:12:01.882 --> 00:12:04.380 So this is great use of inheritance. 241 00:12:04.380 --> 00:12:06.964 What I'm going to do, though, is finish by splitting 242 00:12:06.964 --> 00:12:10.213 the old-style call to the grid method. 243 00:12:10.213 --> 00:12:13.110 So I'm gonna come back here and look at it on, 244 00:12:13.110 --> 00:12:14.527 here in the code. 245 00:12:15.551 --> 00:12:17.215 And what I might do is just separate this 246 00:12:17.215 --> 00:12:19.286 on to two lines, even though we haven't 247 00:12:19.286 --> 00:12:21.471 actually got an error, we have actually 248 00:12:21.471 --> 00:12:22.508 quite a long line there. 249 00:12:22.508 --> 00:12:23.713 So even though it's only a comment, 250 00:12:23.713 --> 00:12:26.294 what I'm going to do is after the rowspan, 251 00:12:26.294 --> 00:12:29.157 we'll just put this on a separate line. 252 00:12:29.157 --> 00:12:30.635 All right, so at this point now we're ready 253 00:12:30.635 --> 00:12:35.580 to continue and take this scrollbox class further. 254 00:12:35.580 --> 00:12:36.882 And what we'll do in the next video 255 00:12:36.882 --> 00:12:40.185 is we'll start work on creating a subclass of scrollbox 256 00:12:40.185 --> 00:12:42.941 that populates itself from the database. 257 00:12:42.941 --> 00:12:45.358 So see you in the next video.