WEBVTT

0
00:00.570 --> 00:03.480
Now coming back to our main.py

1
00:03.780 --> 00:07.170
our previous program had a label,

2
00:07.200 --> 00:10.320
a button and an entry, and it was relatively simple.

3
00:10.740 --> 00:13.560
So I'm going to head back to this main.py file

4
00:13.830 --> 00:18.570
where we've got only three widgets so that I can show you how we can define the

5
00:18.570 --> 00:22.350
layout and positioning of each of our widgets.

6
00:23.460 --> 00:28.380
Firstly, I've reconfigured the file a little bit. So I've moved the button

7
00:28.380 --> 00:30.060
_clicked function to the top,

8
00:30.540 --> 00:35.540
and I've made sure that each of the pack methods are at the very end of each

9
00:37.110 --> 00:41.760
widget. That way we'll be able to work with it quite easily. Now,

10
00:41.760 --> 00:45.930
as I mentioned before, tkinter has a whole bunch of different layout

11
00:45.930 --> 00:50.930
managers that define how to position each of the widgets in your GUI program.

12
00:52.440 --> 00:56.340
Now there's three that you should know about, pack, place and grid.

13
00:57.270 --> 00:58.080
Now, firstly,

14
00:58.080 --> 01:03.080
we've already seen pack and all that pack does is it basically packs each of the

15
01:04.320 --> 01:08.340
widgets next to each other in a vaguely logical format.

16
01:08.970 --> 01:10.470
And by default, pack

17
01:10.470 --> 01:15.470
will always start from the top and then pack every other widget just below the

18
01:15.600 --> 01:18.360
previous one. As I mentioned,

19
01:18.390 --> 01:23.390
you can change this by adding a side parameter and you can change it to for

20
01:24.840 --> 01:27.360
example, side = left.

21
01:27.900 --> 01:31.200
And if you change this for all of the packs,

22
01:31.260 --> 01:36.090
then it's going to pack everything starting from the left edge of the program

23
01:36.390 --> 01:40.890
like this. And you can change that to bottom or right as well.

24
01:41.550 --> 01:46.550
But the problem with pack is that it's actually quite difficult to specify a

25
01:46.800 --> 01:49.080
precise position. So for example,

26
01:49.080 --> 01:53.370
if you wanted this label to be a little bit up and then this button a little bit

27
01:53.370 --> 01:57.240
down and this entry all the way to the right. It's very,

28
01:57.240 --> 01:59.910
very complicated to do that using pack.

29
02:00.390 --> 02:03.360
And that's why there's not just a single layout manager,

30
02:03.390 --> 02:06.870
but there's lots of others. So let's take a look at the next one,

31
02:06.870 --> 02:11.760
which is called place. Place is all about precise positioning.

32
02:12.300 --> 02:14.430
So when you place something,

33
02:14.910 --> 02:18.870
you can provide a X and Y value. So for example,

34
02:18.870 --> 02:22.890
I can say my label.place, and then I can say, well,

35
02:22.890 --> 02:27.300
the X value should equal 0 and the Y value should equal 0.

36
02:27.720 --> 02:31.500
And this just places that label at the top left corner.

37
02:32.160 --> 02:36.270
Now it's important to remember that if a widget gets created

38
02:36.570 --> 02:41.010
but it doesn't have any layout specified it using pack, place or grid,

39
02:41.250 --> 02:43.920
then it won't be shown as you can see here,

40
02:43.920 --> 02:48.920
we've only got the label showing up. Now that we've placed our label to the top

41
02:49.200 --> 02:52.110
left corner, we can try placing it in somewhere else.

42
02:52.380 --> 02:55.260
So let's move it a little bit along the X axis.

43
02:55.290 --> 02:58.350
So let's say place it on a (100, 0)

44
02:58.800 --> 03:02.320
That moves it to the right a bit more, and if we want to move it down

45
03:02.320 --> 03:04.570
we can change the Y position.

46
03:04.930 --> 03:09.310
So now it's down at the bottom and then the X is 100. Now,

47
03:09.310 --> 03:13.750
remember we've defined the width and height. So the width is 500 pixels,

48
03:13.750 --> 03:17.440
the height is 300 pixels and anywhere along that screen,

49
03:17.710 --> 03:22.710
you can define a X and Y value for a particular widget to place it at that

50
03:23.380 --> 03:24.760
precise position.

51
03:25.630 --> 03:30.630
The downside of place on the other hand is the fact that it is so specific and

52
03:31.540 --> 03:36.010
we have to work out in our head the coordinate and where to put each widget.

53
03:36.400 --> 03:39.820
It simple enough if you've only got three widgets like we have here,

54
03:40.120 --> 03:42.490
but if you have a hundred or fifty,

55
03:42.490 --> 03:46.870
then that becomes quickly a bit of a nightmare to manage the precise coordinates

56
03:46.930 --> 03:47.920
of each widget.

57
03:48.910 --> 03:53.260
So in addition to pack and place, there's also a final layout manager

58
03:53.350 --> 03:55.300
which also happens to be my favorite one,

59
03:55.660 --> 04:00.160
which is the grid. And the grid is a really simple concept.

60
04:00.490 --> 04:05.490
It imagines that your entire program is a grid and you can divide it into any

61
04:06.640 --> 04:08.770
number of columns and rows that you want to.

62
04:09.190 --> 04:13.660
So just as a reminder, the rows are the ones that go along the horizontal and

63
04:13.660 --> 04:16.450
the columns are the ones that go along the vertical.

64
04:17.530 --> 04:22.330
If I remove my place and instead I use my grid,

65
04:22.630 --> 04:25.330
I could say my_label.grid,

66
04:25.660 --> 04:29.680
and then I can provide a column and a row number.

67
04:29.710 --> 04:34.120
So let's say I'm going to put it at the first column and the first row.

68
04:34.150 --> 04:38.320
So then starts from zero so that we could say column = 0, row =

69
04:38.320 --> 04:42.010
0. And you can see that it gets placed in the top left corner.

70
04:42.760 --> 04:47.170
Now the grid system is relative to other components.

71
04:47.410 --> 04:52.240
So even if I change this column to, I dunno, five and the row to five,

72
04:52.600 --> 04:55.750
you can see that it doesn't actually change the layout because there is no

73
04:55.750 --> 04:58.990
widget in column four, three, two or one.

74
04:59.200 --> 05:01.900
So it's still the first one in the grid.

75
05:03.340 --> 05:05.620
So the easiest way of working with the grid

76
05:05.650 --> 05:08.830
is starting with the things that you want it to be at the top left,

77
05:09.070 --> 05:12.010
defining a starting column and rows, zero, zero,

78
05:12.370 --> 05:17.320
and then for the next and subsequent widgets to just keep going through it and

79
05:17.350 --> 05:20.530
define its position on the grid. For example,

80
05:20.530 --> 05:25.530
if I wanted the button to be on column one and row one

81
05:27.970 --> 05:30.580
and then I want my entry

82
05:30.610 --> 05:35.610
which is called input to be on the grid in column two and row two,

83
05:39.580 --> 05:41.230
now if you run this,

84
05:41.260 --> 05:45.100
you can see it's now been laid out along our grid.

85
05:45.640 --> 05:48.040
And this is effectively what it looks like.

86
05:48.400 --> 05:51.160
Our label is in column zero row

87
05:51.160 --> 05:53.590
zero, button in column one row

88
05:53.590 --> 05:56.860
one and entry in column two row two.

89
05:58.130 --> 06:03.130
This is one of the easiest ways of visualizing and creating the layout for your

90
06:03.920 --> 06:07.400
tkinter programs. And it's really flexible

91
06:07.490 --> 06:10.850
and it's really easy to imagine and understand.

92
06:11.120 --> 06:16.100
So this is always my preferred way of working with the layout for 

93
06:16.130 --> 06:18.620
tkinter. Just a word of warning though.

94
06:18.650 --> 06:23.650
You can't mix up grid and pack in the same program.

95
06:23.990 --> 06:28.760
So for example, if I wanted my label and my button to be defined by the grid

96
06:29.060 --> 06:34.060
but then I decide to use the pack method for my final entry,

97
06:35.600 --> 06:40.580
then you can see I actually get a error when I run my code. It says,

98
06:40.610 --> 06:43.070
cannot use geometry manager pack

99
06:43.250 --> 06:45.980
which already has slaves managed by grid.

100
06:46.370 --> 06:49.010
So these two are incompatible with each other. 

101
06:49.010 --> 06:51.890
You basically have to choose one or the other.

102
06:52.490 --> 06:57.050
And often I will choose grid because it's just more flexible and more easy to

103
06:57.050 --> 07:00.980
understand. So now here comes a challenge for you.

104
07:01.520 --> 07:06.380
I want you to change the code that we've already written so that we end up with

105
07:06.380 --> 07:10.310
this layout. So we've already got a label, a button and an entry.

106
07:10.670 --> 07:15.650
I want you to add a new button and it should be positioned like this.

107
07:15.950 --> 07:19.940
Have a think about how you might solve this challenge using the grid system that

108
07:19.940 --> 07:23.750
you learned about just now. Pause the video and complete the challenge.

109
07:25.400 --> 07:29.510
All right. So the first thing you notice is that the label is still at column

110
07:29.510 --> 07:33.590
zero row zero, button is still at row one column one,

111
07:33.980 --> 07:38.690
but this new button is now at row zero column two.

112
07:39.350 --> 07:41.060
So let's go ahead and create it.

113
07:41.960 --> 07:46.370
Now I'm just going to create a new button and I'm not going to worry about its

114
07:46.370 --> 07:47.720
command or any of that.

115
07:48.050 --> 07:51.830
I'll give it a piece of text just so that we can identify it and I'll call it

116
07:51.830 --> 07:52.700
new button.

117
07:53.240 --> 07:57.530
But then the most important thing is how we lay out this new button.

118
07:58.010 --> 08:02.990
So I'm going to use the grid system and I'm going to give it a column of two

119
08:03.260 --> 08:05.990
because it is zero, one, two,

120
08:06.170 --> 08:10.550
the third column from the left and then row is going to be zero.

121
08:13.580 --> 08:17.090
Now, when I run this code though, you'll notice something a little bit odd.

122
08:17.510 --> 08:21.980
Why is the entry below the button? Because in our example,

123
08:22.040 --> 08:26.750
the entry is actually over on the right of this new button in a new column.

124
08:27.500 --> 08:31.520
By putting this new button in between the old button and the entry, we've

125
08:31.520 --> 08:34.940
actually changed the positioning of that entry on the grid.

126
08:35.240 --> 08:39.350
So we've actually had to move it along into the next column.

127
08:39.950 --> 08:41.000
So to do that,

128
08:41.030 --> 08:46.030
we have to change the grid of our entry instead of having column two,

129
08:46.520 --> 08:51.380
to make it column three, just so that its on the right of this new button.

130
08:52.130 --> 08:55.890
And now when I run it, this has the exact layout that we wanted

131
08:56.280 --> 09:01.080
and we've now learned a little bit about how we can precisely position our

132
09:01.080 --> 09:06.080
widgets in our program using the pack, place, and grid layout managers.

133
09:08.610 --> 09:13.610
The very last thing I want to show you with relation to layout and design of our

134
09:14.730 --> 09:19.320
GUI programs is how to add a little bit of padding around components.

135
09:19.920 --> 09:24.920
The easiest way to add padding is actually to directly modify the widgets.

136
09:25.410 --> 09:26.310
So for example,

137
09:26.310 --> 09:30.450
if I wanted a bit of padding around all of the elements in my window,

138
09:30.450 --> 09:33.570
so basically added around the edge of the window,

139
09:33.960 --> 09:38.960
then I could simply say window.config and I can change the padding in the X

140
09:42.060 --> 09:45.900
axis and the padding in the Y axis,

141
09:45.930 --> 09:48.360
so padx and pady.

142
09:48.870 --> 09:51.990
So now if I run this program as it is,

143
09:52.290 --> 09:57.290
you can see that there's now more space being added around all four edges of our

144
09:58.320 --> 10:02.190
program. Now I can make this a lot more extreme.

145
10:02.190 --> 10:07.190
So let's say I add the padx to be 100 and the pady to be 200,

146
10:08.610 --> 10:11.340
you can see just how much padding we've now added.

147
10:12.450 --> 10:16.170
And this just means that you add more space around your program and it makes

148
10:16.170 --> 10:19.380
things easier to see and looks a little bit nicer.

149
10:20.670 --> 10:25.080
If you want to add padding around a specific widget not just the entire window,

150
10:25.350 --> 10:30.350
then you can do the same with that widget. So we could get hold of my label and

151
10:30.480 --> 10:30.750
again

152
10:30.750 --> 10:35.750
using config to change the padx and the pady. So let's add, maybe I dunno,

153
10:36.720 --> 10:41.310
50 pixels of padding in the X and in the Y.

154
10:43.320 --> 10:45.570
Now you can see that around that label

155
10:45.600 --> 10:50.490
there's a whole lot of space so that it pushes everything else away and actually

156
10:50.490 --> 10:53.010
makes the entire program window a lot bigger.

157
10:53.640 --> 10:58.640
So this is just a way for you to be able to add space around your widgets so

158
10:59.160 --> 11:00.840
that they're not all crushed together

159
11:01.080 --> 11:03.480
and it helps you with your layout and your design.