WEBVTT 1 00:00:01.960 --> 00:00:06.259 ok so moving on in the last video you can see what we've got up to we've got the 2 00:00:06.259 --> 00:00:11.480 interface working you can see below and we are getting closer to what we're trying to achieve here we still got 3 00:00:11.480 --> 00:00:15.610 some issues we've got to fix this left hand border up so we can move things over 4 00:00:15.610 --> 00:00:19.759 because obviously its too far to the left so we will do that shortly but we also need 5 00:00:19.759 --> 00:00:25.450 to add the ok and cancel button so lets do that next and we want to align those to the right 6 00:00:25.450 --> 00:00:30.750 edge so that they appear close to each other so we get back to the code to do that we're 7 00:00:30.750 --> 00:00:38.250 going to have these buttons so... 8 00:00:38.250 --> 00:00:41.670 ..... 9 00:00:41.670 --> 00:00:48.480 ...we are going to add that 10 00:00:48.480 --> 00:00:54.420 but we're going to add a command to quit as well I'll show you how to do that I have simple command you can 11 00:00:54.420 --> 00:01:01.309 actually call that as well so.... 12 00:01:01.309 --> 00:01:04.809 ...and extra points if you can remember how to go about doing that we did something 13 00:01:04.809 --> 00:01:10.990 similar earlier in the code and it's using command so..... 14 00:01:10.990 --> 00:01:19.930 ...so we need to specify the command so....basically if the 15 00:01:19.930 --> 00:01:25.049 cancel button is clicked it is going to close it down ok so we specify those 16 00:01:25.049 --> 00:01:34.560 we now need to add them to the grid so.... 17 00:01:34.560 --> 00:01:38.399 ...... 18 00:01:38.399 --> 00:01:46.619 ....... 19 00:01:46.619 --> 00:01:55.789 ...so thay you can see the OK button 20 00:01:55.789 --> 00:02:00.869 is going to the east going right and the cancel button is going west to 21 00:02:00.869 --> 00:02:03.939 the left so therefore their aligned close next to each other 22 00:02:03.939 --> 00:02:08.110 basically so the edges appeared close to each other and you can probably 23 00:02:08.110 --> 00:02:11.530 guess this mainWindow.quit it actually closes down so its equivalent of us 24 00:02:11.530 --> 00:02:12.150 clicking on 25 00:02:12.150 --> 00:02:15.769 the close button in a window so it does it automatically if the cancel button is 26 00:02:15.769 --> 00:02:18.220 pressed two things to say about that though 27 00:02:18.220 --> 00:02:21.689 first things we should really probably use destroy instead of quit although 28 00:02:21.689 --> 00:02:26.060 quits gonna work destroys actually kinder sounds weird destroyed sounds worst 29 00:02:26.060 --> 00:02:30.890 that quit because it just stops the main loop and deletes the widget and all 30 00:02:30.890 --> 00:02:35.060 child widgets that's what destroyed does but quit method also stops the TCL 31 00:02:35.060 --> 00:02:38.200 interpreter so you may have problems if you're on your program in idle for 32 00:02:38.200 --> 00:02:42.939 example because idle itself is written into TKinter so it's probably a 33 00:02:42.939 --> 00:02:55.370 good idea to use destroy but having said that quit will work so lets run it and cancel an 34 00:02:55.370 --> 00:03:00.010 interesting enough canceled doesn't work now this is a very common mistake to make when 35 00:03:00.010 --> 00:03:03.079 dealing with widget callback functions and this is why we are going to be 36 00:03:03.079 --> 00:03:07.549 labeling the point slightly the correct way to assign the function to the 37 00:03:07.549 --> 00:03:11.629 command properties is to just use the function name in this case mainWindow.quit 38 00:03:11.629 --> 00:03:17.280 and if we come back and have a look at the code notice how I put the brackets on the end and 39 00:03:17.280 --> 00:03:19.980 if your using any other programming language it probably very familiar with 40 00:03:19.980 --> 00:03:24.690 that but when we use parentheses after the function name were actually calling 41 00:03:24.690 --> 00:03:28.150 the function and the result of the functions assigned to the command 42 00:03:28.150 --> 00:03:32.409 property now the quit method returns none so the result is that clicking the 43 00:03:32.409 --> 00:03:36.560 command or sorry the cancel button does nothing because main Windows mainly 44 00:03:36.560 --> 00:03:40.870 hasn't been started at a point when quit is executed the loop is not terminated so 45 00:03:40.870 --> 00:03:44.040 the incorrect assignment doesn't cause problems but it also doesn't work either 46 00:03:44.040 --> 00:03:48.139 so we can try we can change that leave it as it is leave that brackets as it is 47 00:03:48.139 --> 00:03:53.019 but change it to destroy...... 48 00:03:53.019 --> 00:04:00.550 it would help if I type it correctly...now run that 49 00:04:00.550 --> 00:04:04.250 now we get an error you see we haven't even been able to run the program and the error is 50 00:04:04.250 --> 00:04:09.460 can't invoke button command application has been destroyed so the value know is still being assigned 51 00:04:09.460 --> 00:04:13.690 to the command property but the destroy method deletes the mainWindow widget 52 00:04:13.690 --> 00:04:17.290 and all the widgets placed inside so in actual fact the cancel button 53 00:04:17.290 --> 00:04:21.000 itself is destroyed by the line of code when the command properties being 54 00:04:21.000 --> 00:04:25.360 sent and your error message states the application has been destroyed so what we need to do is correct the 55 00:04:25.360 --> 00:04:30.350 assignment and the program will run fine so close it down the main thing is again for these types 56 00:04:30.350 --> 00:04:34.480 of things we don't specify the parentheses because we don't want the function to 57 00:04:34.480 --> 00:04:38.790 run we are assigning the function to be called when the buttons is click so that's 58 00:04:38.790 --> 00:04:43.140 why there's no parentheses there and early on in the code we had command 59 00:04:43.140 --> 00:04:49.140 use on line 33 notice I didn't have parentheses after that either 60 00:04:49.140 --> 00:04:55.190 so no we've done that we should be able to run this and haven't got a crash which is good and 61 00:04:55.190 --> 00:05:01.150 there's our demo we should be able to click canceled and you can see that it's exited and we're 62 00:05:01.150 --> 00:05:06.760 back at the IntelliJ with program close which is good so in the 63 00:05:06.760 --> 00:05:10.620 previous video I've talked about rbValue.get we tried a few different values just to 64 00:05:10.620 --> 00:05:14.650 see how the value change depending on what radio button was clicked but also we're 65 00:05:14.650 --> 00:05:18.430 changing the value set on line 43 so come back and have a look 66 00:05:18.430 --> 00:05:22.930 sorry line 42 so once it should check the file name it to should check path so if I run it again to 67 00:05:22.930 --> 00:05:31.430 refresh what where up to so we got file name paths so the currently the values is set to 2 so its going 68 00:05:31.430 --> 00:05:35.940 to be defined as path so we will leave it as that but we can change it as 69 00:05:35.940 --> 00:05:38.470 the default if you wanna have that as a default and that's effectively what we've 70 00:05:38.470 --> 00:05:42.800 done their on line 42 set it up so that the first time we run this every 71 00:05:42.800 --> 00:05:46.250 time we run the program that's going to be the default options if you wanted the first one to be the 72 00:05:46.250 --> 00:05:54.780 default option just change it to one run the program again 73 00:05:54.780 --> 00:06:02.570 now we got the default being the file name now there's one other improvement we can make everything is about to close the 74 00:06:02.570 --> 00:06:05.680 edges as I mentioned at the start of the video so we should really add a bit of 75 00:06:05.680 --> 00:06:09.000 padding so I'm going to add some code here at the top right up here 76 00:06:09.000 --> 00:06:13.960 lets add it strait after the geometry to do some padding to the left hand side 77 00:06:13.960 --> 00:06:17.650 so you've seen padx before so I'm going to be something similar..... 78 00:06:17.650 --> 00:06:25.680 .....try running that 79 00:06:25.680 --> 00:06:35.140 and see what it looks and we now got that padding to the left hand side so that's everything not flush 80 00:06:35.140 --> 00:06:40.680 against side now so it's much better for us but the one thing about this layout I'll bring up the 81 00:06:40.680 --> 00:06:43.830 other ones so you can see what we're comparing it against one thing about 82 00:06:43.830 --> 00:06:47.530 this layout is that we haven't looked at in detail at the moment and it deserves to be 83 00:06:47.530 --> 00:06:51.200 looked at is the weight property of the rows and columns so how do we 84 00:06:51.200 --> 00:06:55.950 arrive at the weight values and that's the values we've used here in line 85 00:06:55.950 --> 00:07:01.570 17 through 26 so what exactly are these values doing and what do they mean well the 86 00:07:01.570 --> 00:07:07.790 weight property probably doesn't do what may at first appear to do and we actually got an admission to make those 87 00:07:07.790 --> 00:07:12.100 values were largely just made up in fact there's a whole range of weights 88 00:07:12.100 --> 00:07:15.460 we could have used to get pretty much exactly the same appearance as the 89 00:07:15.460 --> 00:07:18.840 values we've use so let's have a look at how weight does behave and why 90 00:07:18.840 --> 00:07:22.950 its not necessary to produce exact values for it so one nice thing about the 91 00:07:22.950 --> 00:07:26.220 IntelliJ product is that you can run a Python program without terminating a 92 00:07:26.220 --> 00:07:31.070 previous execution so we are going to use that to make changes to the code and the compare 93 00:07:31.070 --> 00:07:34.940 the results with the previous execution just to see what effect the changes have 94 00:07:34.940 --> 00:07:36.560 had to that program 95 00:07:36.560 --> 00:07:40.650 and by dragging the GUI screens next to each other above and below we can compare the precise 96 00:07:40.650 --> 00:07:46.050 placement of the widgets after each change and so let's do that now so stop the program 97 00:07:46.050 --> 00:07:51.810 and run again propbably don't need to do that but will run it again so we got one copy running 98 00:07:51.810 --> 00:07:56.890 that's is going to be our test version do that first and then let's go back and 99 00:07:56.890 --> 00:08:04.990 change all the weights on lines 17 through 26 change them all to 1 and run the program again...... 100 00:08:04.990 --> 00:08:23.860 ...and run again oops typo and run it again....and now we've got two versions running and lets have look at what's 101 00:08:23.860 --> 00:08:24.770 changed 102 00:08:24.770 --> 00:08:29.450 firstly we have a look at what's horizontals so just look at the 103 00:08:29.450 --> 00:08:33.020 horizontal alignments of the 2 you can see that that setting all the column weights to 1 104 00:08:33.020 --> 00:08:36.070 really has made very little difference in the horizontal placement of the widgets 105 00:08:36.070 --> 00:08:41.260 so you have might expected columns in the weight of 3 to be 3 times wider than column 0 and 1 which only 106 00:08:41.260 --> 00:08:44.290 had a weight of one but obviously this is not the case and the width of the first 107 00:08:44.290 --> 00:08:48.350 two columns has grown really only slightly you can their is a slightly wider their 108 00:08:48.350 --> 00:08:53.910 now than it was in the top example which was our first version before we made the 109 00:08:53.910 --> 00:08:58.090 changes so the width and the columns and heights of the rows are determined by 110 00:08:58.090 --> 00:09:02.420 the sizes of the widgets placed in them and the weight properties used when the 111 00:09:02.420 --> 00:09:06.980 window is resized so column with the weight of three will widen 3 times more 112 00:09:06.980 --> 00:09:12.200 faster than a column with a weight of one when the window size increases so just trying to 113 00:09:12.200 --> 00:09:18.210 keep the windows overlay what we are going to do is just resize and start on that we're 114 00:09:18.210 --> 00:09:24.220 going to make it roughly twice the size so start with the top one 115 00:09:24.220 --> 00:09:29.230 roughly twice the size it doesn't have to be precies but we'll do the same thing to this one what I'm going to do is 116 00:09:29.230 --> 00:09:38.230 just set it there and expand so its roughly the same size and move this down a little bit so 117 00:09:38.230 --> 00:09:44.460 we got space here so the list box now in the second wind where all the weights are equal 118 00:09:44.460 --> 00:09:48.120 is now wider than the original window with a weight of 3 the last three columns grew 119 00:09:48.120 --> 00:09:51.680 faster than the first 2 which meant their wasn't really as much room for list box 120 00:09:51.680 --> 00:09:55.730 to get wider as the windows were re-sized know all the columns have the same weight the 121 00:09:55.730 --> 00:09:59.470 list box can grow at the same rate as all the others so the list boxes now 122 00:09:59.470 --> 00:10:02.950 wider than what it was originally so gonna set them back to roughly the size they 123 00:10:02.950 --> 00:10:16.270 were..... 124 00:10:16.270 --> 00:10:22.870 ....so you can see how the row heights actually behave because the noticeable 125 00:10:22.870 --> 00:10:26.180 difference in the sizing between the results label and the entry box for 126 00:10:26.180 --> 00:10:32.140 example like this code here this is significantly different here so with original weight of 10 for row 1 row 127 00:10:32.140 --> 00:10:36.170 2 containing the results doesn't re-size very quickly compared to row 128 00:10:36.170 --> 00:10:41.520 one but when all weights are equal its height increases at the same rate now because 129 00:10:41.520 --> 00:10:45.570 we've align the label with the top of the cell and the entry box at the bottom the 130 00:10:45.570 --> 00:10:50.300 greater row height now becomes apparent as you can see on the right hand side so 131 00:10:50.300 --> 00:10:53.670 when placing to widgets in the same cell it's generally a good idea to give 132 00:10:53.670 --> 00:10:57.860 the row or column a low weighting and that's to prevent unsightly behavior 133 00:10:57.860 --> 00:11:02.570 like this which is not a good look when the window is started now if the 134 00:11:02.570 --> 00:11:07.080 widgets are stacked above each other like here set the weight low 135 00:11:07.080 --> 00:11:11.800 and in if they are next to each other use the low column weight another tip is that there's very 136 00:11:11.800 --> 00:11:16.570 little value in row 0 it's really just a title for the window so give that row a 137 00:11:16.570 --> 00:11:20.750 low weight compared to the rows that actually have content and you can 138 00:11:20.750 --> 00:11:24.870 see this bit by re sizing each window vertically which I'm gonna do now just do 139 00:11:24.870 --> 00:11:31.900 that and just compare our results so...... 140 00:11:31.900 --> 00:11:39.720 .....you can see now that I've done that I 141 00:11:39.720 --> 00:11:47.390 resize them vertically that row 0 occupies far more space than its contents warrant in the 142 00:11:47.390 --> 00:11:50.820 second example because we really wanted to stay at the top because it doesn't 143 00:11:50.820 --> 00:11:53.700 really need that extra space in face start looking and that's meant to 144 00:11:53.700 --> 00:11:57.720 be a title so with the layout like this one when re-sizing vertically there's really only 145 00:11:57.720 --> 00:12:02.820 one widget that benefits from growing and that's the listbox that's why it had a 146 00:12:02.820 --> 00:12:07.840 greater weight originally so the values I guess weren't entirely made up but 147 00:12:07.840 --> 00:12:12.170 when re-sizing horizontally the list box can still benefit for it for some extra space but maybe 148 00:12:12.170 --> 00:12:15.770 so could the results box over here as well so that could be an indication that 149 00:12:15.770 --> 00:12:19.820 we shouldn't have put it in the same column possibly as the radio buttons so tied 150 00:12:19.820 --> 00:12:23.360 to the list box is the scroll bar but there is a problem with that when we re-size horizontally 151 00:12:23.360 --> 00:12:27.990 so gonna close both of these now 152 00:12:27.990 --> 00:12:34.540 so if we go through and undo those changes I'm gonna close down the run window and control 153 00:12:34.540 --> 00:12:38.040 z on the computer under to undo the changes or in my case its MAC I'm 154 00:12:38.040 --> 00:12:47.620 doing command z I'm just going back change all the code so we got it back to what it was 155 00:12:47.620 --> 00:12:57.290 before does changes so if we run the program again now let's try shrinking 156 00:12:57.290 --> 00:13:01.060 the window horizontally and watch what happens to the scroll bar 157 00:13:01.060 --> 00:13:07.120 ...see it doesn't take long for the scroll bar to actually disappear obviously their are other issues on the 158 00:13:07.120 --> 00:13:11.709 screen as well but the scroll bars is very quick to disappear when we do that so at 159 00:13:11.709 --> 00:13:16.720 this point people who haven't got a mouse wheel obviously I got one so I can scroll it 160 00:13:16.720 --> 00:13:20.459 up but if someone doesn't have one the only way they going to be able to 161 00:13:20.459 --> 00:13:23.230 scroll at this point is to use the arrows which I'm using up and down now and 162 00:13:23.230 --> 00:13:27.560 clearly that is not an option for everyone we don't want to force people to have to use only one 163 00:13:27.560 --> 00:13:34.160 way to scroll the values from our list box and even if it doesn't vanish so open 164 00:13:34.160 --> 00:13:38.520 up a little bit so the case it hasn't vanish as you can see very quickly its 165 00:13:38.520 --> 00:13:42.160 actually getting really really thin and its really not usable so remember that 166 00:13:42.160 --> 00:13:45.980 if a column grows more quickly when the windows made wider its also going to 167 00:13:45.980 --> 00:13:50.300 shrink more quickly when the window becomes narrower so what to do is to protect the scroll bar 168 00:13:50.300 --> 00:13:54.089 column by giving it a much lower weight than all the other columns for that 169 00:13:54.089 --> 00:13:57.959 reason so it doesn't make much sense for scroll bar to get wide anyways so a low 170 00:13:57.959 --> 00:14:02.820 weight relative to the other columns solves both issues here so 171 00:14:02.820 --> 00:14:06.380 its also a good reason to place scroll bars in their own columns or rows for a 172 00:14:06.380 --> 00:14:13.779 horizontal scroll bar so looking at the ok button its roughly half the width 173 00:14:13.779 --> 00:14:18.329 of the cancel button and as you make the window narrower it starts to disappear you can see that pretty 174 00:14:18.329 --> 00:14:22.300 quickly its disappearing there so its columns should probably have roughly half the weight of 175 00:14:22.300 --> 00:14:27.060 column 4 also because the radio buttons at the top are not expanded to the 176 00:14:27.060 --> 00:14:30.690 width of the cell unless they susceptible to changes caused by re-sizing so you can 177 00:14:30.690 --> 00:14:36.230 see they are pretty consistent there so that's good in that we can allow our column to 178 00:14:36.230 --> 00:14:37.810 shrink faster 179 00:14:37.810 --> 00:14:41.090 well although most of the documentation mentions the importance and weight when 180 00:14:41.090 --> 00:14:45.210 resizing we haven't come across any that mentions that affects of weight are 181 00:14:45.210 --> 00:14:49.220 generally more important when shrinking window than when expanding it so what we 182 00:14:49.220 --> 00:14:56.040 gonna do is just close this off so let's make a few changes to our column configurations we are gonna change the 183 00:14:56.040 --> 00:15:05.910 weighting so the first one is weight equals a 100..... 184 00:15:05.910 --> 00:15:14.010 .....so if we do that it should 185 00:15:14.010 --> 00:15:19.360 behave in a more user-friendly fashion and hopefully because of what I've discussed 186 00:15:19.360 --> 00:15:24.860 you will understand why its gonna behave that so lets just check that it is going to do that so bring this over again so 187 00:15:24.860 --> 00:15:30.870 now if we try and make it smaller notice the scroll bar is a little bit better now, now we 188 00:15:30.870 --> 00:15:34.220 can't get it perfect because it's physically too small to fit the buttons 189 00:15:34.220 --> 00:15:43.800 we can't really do much about it but you can see this scroll bar is a lot better than what it was and we've 190 00:15:43.800 --> 00:15:46.680 got a better result than what we have in the past and likewise 191 00:15:46.680 --> 00:15:49.970 expanding 192 00:15:49.970 --> 00:15:54.889 not perfect but you can see we're getting there so by starting with a sketch and drawing 193 00:15:54.889 --> 00:15:58.949 a grid on it becomes quite easy to place widgets where you want them and if I run 194 00:15:58.949 --> 00:16:06.470 this again.....and obviously we talked about this a few times but we had these 195 00:16:06.470 --> 00:16:11.819 original sketches and obviously this was done in a Linux 196 00:16:11.819 --> 00:16:15.189 but you could have sketch this out here but this is the part where talking about drawing 197 00:16:15.189 --> 00:16:20.120 grids on them as well to figure out where you can put your items by doing 198 00:16:20.120 --> 00:16:24.120 that it comes quite easy to place widgets where you want them now of course a GUI 199 00:16:24.120 --> 00:16:31.649 builder such as the ones included in Microsoft Visual Studio or Delphi might make life a lot easier by language to be drag and drop but they 200 00:16:31.649 --> 00:16:34.629 are really a convenience rather than as necessity so GUI builders 201 00:16:34.629 --> 00:16:39.899 are available for Python but as we haven't use them we can't give any recommendations 202 00:16:39.899 --> 00:16:43.920 frankly I think you get a lot better mileage by learning to do this manually 203 00:16:43.920 --> 00:16:49.240 you can see that if do that sketch at the start and you understanding how the grid 204 00:16:49.240 --> 00:16:55.220 layout works the grid geometry manager and do some testing as we have shown 205 00:16:55.220 --> 00:17:00.379 you how to do throughout the videos you can pretty well build any interface and you don't 206 00:17:00.379 --> 00:17:06.439 really need to use a graphical builder as such certainly a personal choice but we certainly would 207 00:17:06.439 --> 00:17:10.319 prefer to be building them manually as we've done here because it really helps 208 00:17:10.319 --> 00:17:16.110 strengthen your understanding of Python so just wrapping this up in this example we saw 209 00:17:16.110 --> 00:17:19.280 how to position widgets on the screen obviously you can see our final example 210 00:17:19.280 --> 00:17:23.900 down here of the code we also seen a few of the widgets is available in tk we attached 211 00:17:23.900 --> 00:17:27.169 that scroll bar to another widget and connected them together to get the normal 212 00:17:27.169 --> 00:17:31.230 behavior expected of a scrolling widget and obviously we saw how to populate a list box 213 00:17:31.230 --> 00:17:35.010 and spinner controls and we've been be able to get the results from a group of 214 00:17:35.010 --> 00:17:38.610 radio buttons so obviously there would be a lot more that our UI needs to do in order 215 00:17:38.610 --> 00:17:42.120 to be useful such as responding to clicks on the buttons other than the 216 00:17:42.120 --> 00:17:46.350 cancel which of course we added the code to do and other things like to determine which item 217 00:17:46.350 --> 00:17:51.330 from the list box was selected so all of that requires a user functions but we'll be 218 00:17:51.330 --> 00:17:57.059 talking about functions a few videos on from now in the next we're going to be 219 00:17:57.059 --> 00:17:59.149 doing a challenge so we're gonna come up 220 00:17:59.149 --> 00:18:02.589 and give you a challenge to aid through understanding of tkinter 221 00:18:02.589 --> 00:18:03.809 so we will see you in that next video