1
00:00:05,150 --> 00:00:06,410
So in the last few videos,

2
00:00:06,410 --> 00:00:10,060
we've looked at the *args and **kwargs parameters

3
00:00:10,060 --> 00:00:12,480
and how we can pass on arguments that we don't need

4
00:00:12,480 --> 00:00:15,010
to handle or in fact don't even know about.

5
00:00:15,010 --> 00:00:17,540
So now it's time to create our own listbox class

6
00:00:17,540 --> 00:00:19,870
that includes its own scrollbar.

7
00:00:19,870 --> 00:00:21,770
Now if we had to start this from scratch,

8
00:00:21,770 --> 00:00:24,490
frankly, it would be a mammoth undertaking.

9
00:00:24,490 --> 00:00:26,550
We'd have to learn another language to start with,

10
00:00:26,550 --> 00:00:28,570
TCL, which is prounounced tickle,

11
00:00:28,570 --> 00:00:31,830
which is what the Python TKinter library uses

12
00:00:31,830 --> 00:00:33,700
to produce all its GUI elements.

13
00:00:33,700 --> 00:00:37,180
But fortunately, we already have a working listbox class

14
00:00:37,180 --> 00:00:40,360
and we can inherit most of the behaviour from that.

15
00:00:40,360 --> 00:00:43,570
So back in jukebox.py, I'm gonna open that up again.

16
00:00:43,570 --> 00:00:46,080
We're going to start some work on that.

17
00:00:46,080 --> 00:00:48,270
We're gonna create a scrollable listbox class

18
00:00:48,270 --> 00:00:51,820
and I'm gonna call that, unoriginally, scrollbox.

19
00:00:51,820 --> 00:00:53,920
So I'm gonna go start this at the top of the file

20
00:00:53,920 --> 00:00:58,490
and it's gonna be after the connect, the SQL connect.

21
00:00:58,490 --> 00:01:00,570
And we'll start this on line 10.

22
00:01:00,570 --> 00:01:03,990
So we're gonna start with class scrollbox

23
00:01:05,280 --> 00:01:07,360
and it's tkinter.listbox.

24
00:01:12,070 --> 00:01:13,740
And again, you have to have those two spaces there

25
00:01:13,740 --> 00:01:16,900
between line seven and the start of the class.

26
00:01:16,900 --> 00:01:19,800
And now we wanna define the init method.

27
00:01:19,800 --> 00:01:22,510
So we're gonna do a def underscore underscore

28
00:01:22,510 --> 00:01:24,900
init underscore underscore, and then we're going

29
00:01:24,900 --> 00:01:28,270
to do parentheses, self comes up automatically,

30
00:01:28,270 --> 00:01:32,350
comma, space, window, comma, space, and **kwargs.

31
00:01:35,930 --> 00:01:38,720
And I'm gonna put a note in here for Python 2 users.

32
00:01:38,720 --> 00:01:40,480
So, and I'm gonna comment that out.

33
00:01:40,480 --> 00:01:43,890
And that would be tkinter dot listbox dot

34
00:01:45,670 --> 00:01:49,660
underscore underscore init underscore underscore self

35
00:01:49,660 --> 00:01:52,990
comma space window comma space **kwargs.

36
00:01:56,660 --> 00:01:58,660
So the syntax is gonna be slightly different again

37
00:01:58,660 --> 00:02:00,500
if you're in Python 2.

38
00:02:04,340 --> 00:02:06,490
But in our case, now we're going to,

39
00:02:06,490 --> 00:02:09,880
after that definition, to a super parentheses dot

40
00:02:09,880 --> 00:02:13,410
underscore underscore init, and then we're going to

41
00:02:13,410 --> 00:02:17,580
pass as arguments window comma space, then **kwargs.

42
00:02:20,740 --> 00:02:23,620
And press enter, then a separate line there.

43
00:02:23,620 --> 00:02:27,620
And we're going to do self.scrollbar is equal to

44
00:02:30,250 --> 00:02:34,410
tkinter.scrollbar parentheses window comma space orient

45
00:02:38,240 --> 00:02:41,150
equals tkinter.VERTICAL comma space

46
00:02:43,760 --> 00:02:45,930
command equals self.yview.

47
00:02:50,470 --> 00:02:53,220
And it's just a parentheses, there's no method call there.

48
00:02:53,220 --> 00:02:54,960
So we're just using the right parentheses

49
00:02:54,960 --> 00:02:56,740
to close off the line,

50
00:02:56,740 --> 00:02:57,790
So what I've done there, you can see

51
00:02:57,790 --> 00:02:58,770
it's pretty straightforward.

52
00:02:58,770 --> 00:03:02,190
We started off by overwriting the init method

53
00:03:02,190 --> 00:03:04,060
to add a scrollbar field after calling

54
00:03:04,060 --> 00:03:05,520
the super.init method.

55
00:03:05,520 --> 00:03:07,770
So super and then there's the creation

56
00:03:07,770 --> 00:03:09,160
of the scrollbar field.

57
00:03:09,160 --> 00:03:10,500
And again, the comment of that code

58
00:03:10,500 --> 00:03:14,520
is for Python 2 users, that's the way to init a listbox,

59
00:03:14,520 --> 00:03:18,010
as that would be done with Python 2's old-style classes.

60
00:03:18,010 --> 00:03:19,700
All right, so now that we've done that,

61
00:03:19,700 --> 00:03:23,140
we've defined our base class, we need to change

62
00:03:23,140 --> 00:03:25,550
our listbox types to scrollbox.

63
00:03:25,550 --> 00:03:27,890
So I come down here and we're gonna start

64
00:03:27,890 --> 00:03:29,580
with the artist listbox.

65
00:03:29,580 --> 00:03:32,240
At the moment, we've got tkinter.listbox.

66
00:03:32,240 --> 00:03:36,070
Let's change artistList instead to be equal to

67
00:03:38,000 --> 00:03:42,160
scrollbox and we'll pass the argument as mainWindow.

68
00:03:43,360 --> 00:03:45,810
Then we need to come down and do the same for albums.

69
00:03:45,810 --> 00:03:48,230
And albums we've done here, albumsList here.

70
00:03:48,230 --> 00:03:50,940
Instead of tkinter.listbox, we're going to

71
00:03:50,940 --> 00:03:53,070
make that scrollbox.

72
00:03:53,070 --> 00:03:57,530
Scrollbox and the arguments there is still mainWindow

73
00:03:57,530 --> 00:04:01,150
and listvariable equals albumLV, nothing's changed there.

74
00:04:01,150 --> 00:04:03,120
And then we also need to come down

75
00:04:03,120 --> 00:04:06,230
and do the same for songList.

76
00:04:06,230 --> 00:04:09,370
So that's the songList here, tkinter.listbox.

77
00:04:09,370 --> 00:04:12,700
We're changing that to be our scrollbox.

78
00:04:14,510 --> 00:04:17,510
And the arguments are still mainWindow and listvariable

79
00:04:17,510 --> 00:04:19,579
will equal songLV.

80
00:04:19,579 --> 00:04:20,990
So if we run this

81
00:04:24,590 --> 00:04:27,710
you can see that we've now got our scrollbox objects

82
00:04:27,710 --> 00:04:30,690
created instead of basic listboxes.

83
00:04:30,690 --> 00:04:32,770
And you can see, in fact, the scrollbar's there now.

84
00:04:32,770 --> 00:04:35,020
We can actually use it to scroll up and down.

85
00:04:35,020 --> 00:04:37,740
But essentially, the scrollbox doesn't add anything yet.

86
00:04:37,740 --> 00:04:41,170
But it is a good idea to test your subclasses frequently

87
00:04:41,170 --> 00:04:42,610
when developing them to make sure

88
00:04:42,610 --> 00:04:44,570
that the programme runs without any errors.

89
00:04:44,570 --> 00:04:46,980
And if it does error out, you'll know exactly

90
00:04:46,980 --> 00:04:49,030
where you were before, and it won't take you

91
00:04:49,030 --> 00:04:51,370
hopefully that long to figure out what's changed

92
00:04:51,370 --> 00:04:53,470
since the last time it was working.

93
00:04:53,470 --> 00:04:55,570
But in any event, now that we can replace

94
00:04:55,570 --> 00:04:59,350
the TKlist box class with our scrollbox subclass,

95
00:04:59,350 --> 00:05:02,080
we can start to add that extra functionality.

96
00:05:02,080 --> 00:05:03,920
So we close that down.

97
00:05:05,260 --> 00:05:08,970
And with our calls, we're passing on any keyword arguments

98
00:05:08,970 --> 00:05:11,200
to the listbox init method.

99
00:05:11,200 --> 00:05:13,600
So if we create one of our own scrollbox objects

100
00:05:13,600 --> 00:05:15,360
with a different background, for example,

101
00:05:15,360 --> 00:05:17,400
that would actually work fine.

102
00:05:17,400 --> 00:05:18,630
And just to show you what I mean by that,

103
00:05:18,630 --> 00:05:20,940
we can go back up to artist, the artist listbox

104
00:05:20,940 --> 00:05:23,190
here on line 38 and we could add

105
00:05:23,190 --> 00:05:27,350
an additional argument there, so background equals

106
00:05:28,370 --> 00:05:32,540
blue and if we run this, we get a lovely blue background

107
00:05:34,180 --> 00:05:36,430
from our artists scrollbox.

108
00:05:37,740 --> 00:05:40,330
Or listbox, to be more technically correct.

109
00:05:40,330 --> 00:05:41,350
So in other words, we don't have to worry

110
00:05:41,350 --> 00:05:43,600
about dealing with any options that the users

111
00:05:43,600 --> 00:05:45,410
of our scrollbox decide they want.

112
00:05:45,410 --> 00:05:49,700
We're just passing the lot on in the kwargs argument.

113
00:05:49,700 --> 00:05:51,360
Now black text though on the background's starting

114
00:05:51,360 --> 00:05:54,820
to look awful, so I'm going to actually undo that change

115
00:05:54,820 --> 00:05:57,570
and again, what I mean by that is

116
00:05:59,800 --> 00:06:01,500
it's not really a good look there with that blue,

117
00:06:01,500 --> 00:06:06,410
so I'm going to again just get rid of that blue background

118
00:06:06,410 --> 00:06:07,780
by just undoing it.

119
00:06:07,780 --> 00:06:10,300
I'm gonna go back to how it was now on line 38,

120
00:06:10,300 --> 00:06:11,340
but keep in mind if you do want

121
00:06:11,340 --> 00:06:13,860
to give your scrollboxes different colours and fonts

122
00:06:13,860 --> 00:06:17,350
that's fully supported via the kwargs argument now.

123
00:06:17,350 --> 00:06:19,670
But in our case, we've just created our own subclass

124
00:06:19,670 --> 00:06:22,590
of listbox that we can add extra functionality to,

125
00:06:22,590 --> 00:06:24,150
so let's do as the name suggests

126
00:06:24,150 --> 00:06:26,180
and actually add a scrollbar.

127
00:06:26,180 --> 00:06:28,150
So the time to do that is when our scrollbox

128
00:06:28,150 --> 00:06:30,680
is added to the layout manager.

129
00:06:30,680 --> 00:06:33,270
Now we're only going to support the grid manager

130
00:06:33,270 --> 00:06:34,480
and so consequently to do this

131
00:06:34,480 --> 00:06:36,900
we're going to override the grid method.

132
00:06:36,900 --> 00:06:39,750
So let's go back up to our class definition.

133
00:06:39,750 --> 00:06:41,530
And we're gonna add the code here.

134
00:06:41,530 --> 00:06:44,840
And we'll start the code here on line 18

135
00:06:44,840 --> 00:06:48,050
and we'll define that or override that grid method.

136
00:06:48,050 --> 00:06:52,870
So that's gonna be def grid, self is the first parameter,

137
00:06:52,870 --> 00:06:56,710
then it's comma space row, comma space column,

138
00:06:58,220 --> 00:07:02,390
comma space sticky is equal to nsw in single quotes,

139
00:07:03,850 --> 00:07:06,970
comma space rowspan is equal to one,

140
00:07:06,970 --> 00:07:10,630
comma space columnspan is equal to one,

141
00:07:10,630 --> 00:07:13,460
comma space, you guess it, kwargs.

142
00:07:16,060 --> 00:07:18,840
And Python 2 users, the equivalent would be

143
00:07:18,840 --> 00:07:22,090
tkinter.listbox.grid and I'll just type

144
00:07:25,220 --> 00:07:26,970
this in real quickly.

145
00:07:41,840 --> 00:07:44,610
Again, if you're a Python 2 user.

146
00:07:44,610 --> 00:07:47,320
But in our case, we're now gonna do a super method

147
00:07:47,320 --> 00:07:48,650
called dot grid.

148
00:07:50,100 --> 00:07:54,390
And it's gonna be row equals row, comma space column

149
00:07:54,390 --> 00:07:58,390
equals column, comma space sticky equals sticky,

150
00:08:01,340 --> 00:08:05,500
comma space rowspan equals rowspan, comma space columnspan

151
00:08:08,750 --> 00:08:12,090
equals columnspan, comma space, and yes,

152
00:08:13,120 --> 00:08:15,450
KWargs on the end, **kwargs.

153
00:08:17,780 --> 00:08:18,910
So that's the super call.

154
00:08:18,910 --> 00:08:22,490
Then we also wanna do a self.scrollbar.grid

155
00:08:24,740 --> 00:08:29,530
row equals row, comma space column equals column,

156
00:08:29,530 --> 00:08:33,650
comma space sticky equals in single quotes nse,

157
00:08:33,650 --> 00:08:36,990
comma space, and rowspan equals rowspan.

158
00:08:38,760 --> 00:08:42,059
And then we wanna do a self left to right square brackets

159
00:08:42,059 --> 00:08:44,970
and in single quotes yscrollcommand

160
00:08:47,510 --> 00:08:50,760
and that's equal to self.scrollbar.set.

161
00:08:52,590 --> 00:08:54,540
All right, so the first line in the method

162
00:08:54,540 --> 00:08:57,390
is calling the super, the super class's grid method

163
00:08:57,390 --> 00:08:58,910
and we're passing on any options that

164
00:08:58,910 --> 00:09:00,750
we don't wanna use in kwargs.

165
00:09:00,750 --> 00:09:02,480
And once again in the line above that

166
00:09:02,480 --> 00:09:05,270
I've included the method you'd use for Python 2,

167
00:09:05,270 --> 00:09:07,010
its old-style classes.

168
00:09:07,010 --> 00:09:09,240
Now note that all the options we have included

169
00:09:09,240 --> 00:09:12,600
in our definition of this method won't be present in kwargs.

170
00:09:12,600 --> 00:09:15,150
As we saw in the last video, any additional options

171
00:09:15,150 --> 00:09:17,760
that the calling code uses will just be passed on

172
00:09:17,760 --> 00:09:20,000
to the super classes grid method.

173
00:09:20,000 --> 00:09:23,600
So the remaining code is two lines starting on line 21.

174
00:09:23,600 --> 00:09:25,720
This is just the code we used further down the programme

175
00:09:25,720 --> 00:09:27,280
to display the scrollbar.

176
00:09:27,280 --> 00:09:30,380
Now we use the scrollbar classes grid method

177
00:09:30,380 --> 00:09:32,150
just like we did in the main code.

178
00:09:32,150 --> 00:09:34,200
So we know the row and column because they were

179
00:09:34,200 --> 00:09:37,070
passed into a grid method, so we can put the scrollbar

180
00:09:37,070 --> 00:09:39,180
at the same cell on the grid.

181
00:09:39,180 --> 00:09:41,690
So consequently now, our scrollbar should display

182
00:09:41,690 --> 00:09:43,620
its own scrollbar and we can remove

183
00:09:43,620 --> 00:09:46,380
the scrollbar code from the main programme.

184
00:09:46,380 --> 00:09:47,840
So if we come down to the main code

185
00:09:47,840 --> 00:09:50,620
and I'll just put that up on the screen.

186
00:09:50,620 --> 00:09:54,370
So after the code on line 46, we can actually

187
00:09:55,640 --> 00:09:57,450
delete these four lines.

188
00:09:57,450 --> 00:09:59,180
The blink line and then these other three lines here,

189
00:09:59,180 --> 00:10:03,070
the tkinter.scrollbar, the grid and the yscroll command,

190
00:10:03,070 --> 00:10:04,880
because we're implementing those in our class.

191
00:10:04,880 --> 00:10:07,300
I'm deleting that and likewise for album,

192
00:10:07,300 --> 00:10:08,440
if we go down, we're going to delete

193
00:10:08,440 --> 00:10:09,960
those four lines as well.

194
00:10:09,960 --> 00:10:12,350
One, two, three, four, for the same reason,

195
00:10:12,350 --> 00:10:15,000
we've got it in our own class.

196
00:10:15,000 --> 00:10:16,900
All right, so that now looks a lot neater

197
00:10:16,900 --> 00:10:18,070
and we haven't got the code that

198
00:10:18,070 --> 00:10:22,000
we copy and pasted to create the scrollbars.

199
00:10:22,000 --> 00:10:26,780
Let's just test the programme to make sure that it does work.

200
00:10:26,780 --> 00:10:30,740
And I'm gonna have a look at the output.

201
00:10:30,740 --> 00:10:33,380
And it actually looks like we have got a problem here.

202
00:10:33,380 --> 00:10:35,840
You can see, we've got a scrollbar to the left here.

203
00:10:35,840 --> 00:10:40,610
We've got one for albums, but we haven't got one for songs.

204
00:10:40,610 --> 00:10:42,380
And I click on now what I've done there.

205
00:10:42,380 --> 00:10:44,590
You can see the scrollbar that appears

206
00:10:44,590 --> 00:10:47,630
to be for artists actually works for albums.

207
00:10:47,630 --> 00:10:51,130
So I think I've got my sticky statement wrong.

208
00:10:51,130 --> 00:10:53,780
And we go back and have a look.

209
00:10:53,780 --> 00:10:55,190
So I've got sticky equals nsw,

210
00:10:55,190 --> 00:10:57,220
so we're actually trying to stick the scrollbar

211
00:10:57,220 --> 00:11:00,060
to the west, to the left in other words,

212
00:11:00,060 --> 00:11:02,530
and it should be east, because we want it

213
00:11:02,530 --> 00:11:05,440
to appear to the rightmost part of our listbox.

214
00:11:05,440 --> 00:11:07,760
So I would suspect that's probably the error.

215
00:11:07,760 --> 00:11:09,820
So let's just fix that, or run that rather,

216
00:11:09,820 --> 00:11:11,650
and see that it works.

217
00:11:12,860 --> 00:11:14,060
All right, that looks better to me.

218
00:11:14,060 --> 00:11:15,770
We've got our scrollbar here that's disabled

219
00:11:15,770 --> 00:11:17,660
because we haven't got any entries.

220
00:11:17,660 --> 00:11:19,800
And for songs, we can see there's now a scrollbar.

221
00:11:19,800 --> 00:11:22,430
And we've got the scrollbar that actually works

222
00:11:22,430 --> 00:11:24,920
for albums now, that's much better.

223
00:11:24,920 --> 00:11:26,610
All right, so you can see that they're all working now

224
00:11:26,610 --> 00:11:28,190
and that's good.

225
00:11:28,190 --> 00:11:31,250
Now we could improve it slightly by putting

226
00:11:31,250 --> 00:11:33,660
a check in to the grid method.

227
00:11:33,660 --> 00:11:35,310
At the moment, the scrollbar can only appear

228
00:11:35,310 --> 00:11:37,430
on the right of the listbox.

229
00:11:37,430 --> 00:11:39,210
That's assuming you've got the right sticky commands

230
00:11:39,210 --> 00:11:41,080
pointing, going to the right.

231
00:11:41,080 --> 00:11:43,720
So we could test the value of a sticky that's passed in

232
00:11:43,720 --> 00:11:46,760
and then if it specifies east instead of west,

233
00:11:46,760 --> 00:11:49,190
make the scrollbar sticky to the west.

234
00:11:49,190 --> 00:11:51,020
So I'm not gonna do that now, but give it a go

235
00:11:51,020 --> 00:11:52,540
if that's something you wanna do.

236
00:11:52,540 --> 00:11:56,060
All right, so I'm gonna close that down.

237
00:11:56,060 --> 00:11:59,070
And at this point, we've successfully subclassed

238
00:11:59,070 --> 00:12:02,590
the tkinter listbox to create our own scrollbox,

239
00:12:02,590 --> 00:12:05,170
as well as provide it some additional functionality.

240
00:12:05,170 --> 00:12:07,670
So this is great use of inheritance.

241
00:12:07,670 --> 00:12:10,250
What I'm going to do, though, is finish by splitting

242
00:12:10,250 --> 00:12:13,500
the old-style call to the grid method.

243
00:12:13,500 --> 00:12:16,400
So I'm gonna come back here and look at it on,

244
00:12:16,400 --> 00:12:17,810
here in the code.

245
00:12:18,840 --> 00:12:20,500
And what I might do is just separate this

246
00:12:20,500 --> 00:12:22,570
on to two lines, even though we haven't

247
00:12:22,570 --> 00:12:24,760
actually got an error, we have actually

248
00:12:24,760 --> 00:12:25,790
quite a long line there.

249
00:12:25,790 --> 00:12:27,000
So even though it's only a comment,

250
00:12:27,000 --> 00:12:29,580
what I'm going to do is after the rowspan,

251
00:12:29,580 --> 00:12:32,440
we'll just put this on a separate line.

252
00:12:32,440 --> 00:12:33,920
All right, so at this point now we're ready

253
00:12:33,920 --> 00:12:38,870
to continue and take this scrollbox class further.

254
00:12:38,870 --> 00:12:40,170
And what we'll do in the next video

255
00:12:40,170 --> 00:12:43,470
is we'll start work on creating a subclass of scrollbox

256
00:12:43,470 --> 00:12:46,230
that populates itself from the database.

257
00:12:46,230 --> 00:12:48,640
So see you in the next video.

