Class Checkpoint

TKinter · Part 1 of 2

Tkinter layout: pack(), grid(), place() and frames

Lay out a Python GUI with Tkinter's 3 layout managers, then tidy it up with frames.

Lay out a Python GUI with Tkinter's 3 layout managers, then tidy it up with frames. This lesson joins videos 52 to 55 of my WJEC GCSE Computer Science Unit 2 Python series into one walkthrough. You will stack widgets with pack() and put them side by side with side="left", padx and pady. Then you line up a sign-up form in rows and columns with grid(), using columnspan and sticky="e", put widgets at exact pixel positions with place() and see why it breaks when text or window sizes change, and group widgets inside a Frame so each part of a form can use its own layout. Chapters 0:00 Introduction 0:39 Layout with pack() 2:43 Layout with grid() 6:07 Layout with place() 9:05 Frames 12:04 Summary Each part ends with a "Your turn" task, so pause and try it before the next chapter. From section G, Graphical user interfaces with Tkinter (specification references 2.2.1 and 2.3.1). The narration uses an AI clone of my own voice.
Transcript
  1. Tkinter layout.
  2. In this video, you will learn the 3 ways to lay out widgets in a Tkinter window, and
  3. how to group them with frames.
  4. There are 4 parts. First, you will stack widgets with pack, and put them side by
  5. side with space around them. Next, you will line up labels and entry boxes in rows
  6. and columns with grid. Then you will put widgets at exact positions with place, and
  7. see why it goes wrong when things change size.
  8. Finally, you will group widgets inside frames to build a tidy form.
  9. Each part ends with a task for you to try.
  10. Pause the video when you get there, and try it before you move on.
  11. Part 1. Layout with pack. You will lay out widgets with pack, using side to place
  12. them next to each other, and padx and pady to add space.
  13. Click File, then New File. Import tkinter as tk
  14. and create a 400 by 200 window titled Tuck Shop.
  15. Add the heading label.
  16. Set heading_label equals tk.Label, with the window, text equals
  17. Tuck Shop, and font Arial 16.
  18. Then call heading_label.pack, with pady equals 10 in the brackets.
  19. pady leaves 10 pixels above and below the label.
  20. Add the info_label with the text Choose a snack, and pack it with empty brackets, no
  21. options. It sits under the heading, because pack stacks widgets from the top down.
  22. Add the apple_button with tk.Button and the text Apple.
  23. Call apple_button.pack, with side equals left in speech marks, padx equals
  24. 10, and pady equals 10. Side equals left puts widgets next to each other, and
  25. padx adds space to the left and right.
  26. Add the banana button with the text Banana and the raisins button with the text
  27. Raisins, packed the same way.
  28. Add window.mainloop, save the file as pack_layout.py, and press
  29. F5 to run it. The heading and Choose a snack are centred at the top, one under the
  30. other. Below them, the Apple, Banana and Raisins buttons sit side by side from the
  31. left edge, with 20 pixels between each button.
  32. Now remove side equals left from the 3 buttons and run it again.
  33. The buttons now stack underneath each other.
  34. Put side equals left back, and change padx to 30.
  35. Run it again to see the gaps between the buttons grow.
  36. Your turn. Add a fourth button with the text Crisps, packed the same way as the
  37. others, then run it and check that it appears to the right of Raisins.
  38. Part 2. Layout with grid. You will line up labels and entry boxes in rows and
  39. columns with grid, using sticky and columnspan.
  40. Open IDLE, click File, then New File.
  41. Type import tkinter as tk, then make the window with
  42. window equals tk.Tk, and give it the title "Club Sign Up".
  43. Leave out geometry this time, so the window grows to fit whatever you put in it.
  44. Now the heading. Make heading_label, a label with the text "After School Club"
  45. in Arial, size 14. Then call heading_label.grid, and in the brackets
  46. type row equals 0, column equals 0, columnspan equals 2, and pady
  47. equals 10. Rows and columns count from 0 at the top left.
  48. Columnspan equals 2 lets the heading stretch across both columns, so it sits in the
  49. middle of the form.
  50. Next, the first row of the form.
  51. Make name_label with the text "Name", and grid it in row 1, column 0.
  52. Then make name_entry, an entry box, and grid it in row 1, column
  53. 1. Add padx equals 5 and pady equals 5 to both so they have a little space
  54. around them. Labels go in column 0 and boxes go in column 1.
  55. Add the "Age" and "Form group" rows the same way.
  56. The age label and age entry go in row 2.
  57. The form label, with the text "Form group", and the form entry go in row 3.
  58. Each new row number puts the widgets one line lower.
  59. Press F5 to run it. Look at the labels.
  60. Column 0 is as wide as its longest label, "Form group", so the shorter labels,
  61. "Name" and "Age", sit in the middle of the column.
  62. They do not line up with each other, and that looks untidy.
  63. Close the window and add sticky equals, in speech marks, e, to each label's grid.
  64. Sticky tells a widget which side of its cell to stick to, using compass points.
  65. The letter e means east, which is the right hand side.
  66. Now every label sits on the right of column 0, right next to its box.
  67. Now the button. Make sign_up_button with the text "Sign up".
  68. Grid it in row 4, column 0, with columnspan equals 2, and sticky equals, in speech
  69. marks, e w. The letters e and w mean east and west, so the button stretches
  70. from the left edge to the right edge of both columns.
  71. Add padx equals 5 and pady equals 10.
  72. Finally, type window.mainloop, with brackets, on the last line.
  73. Click File, then Save As, save the file as grid_layout.py, and press
  74. F5 to run it again.
  75. The "Club Sign Up" window shows "After School Club" centred across the top.
  76. Under it are 3 rows, with the labels "Name", "Age" and "Form group"
  77. lined up on the right of column 0, and an entry box beside each in column 1.
  78. The "Sign up" button stretches across the full width at the bottom.
  79. Your turn. Add a fifth field called "Email" in row 4, with its label stuck to the
  80. east and its entry box in column 1, then move the "Sign up" button down to row 5
  81. and run it to check everything still lines up.
  82. Part 3. Layout with place. You will put widgets at exact x and y
  83. positions with place, and see why this is a poor choice when text or window sizes
  84. change.
  85. Open IDLE, click File, then New File.
  86. Type import tkinter as tk, make the window, and give it the title
  87. "Book Return". Then type window.geometry, and in brackets and speech marks,
  88. 300x150, so the window is 300 pixels wide and 150
  89. pixels high.
  90. Make book_label, a label with the text "Book number".
  91. Then call book_label.place, and in the brackets type x equals 20, comma,
  92. y equals 20. The x value is the number of pixels from the left of the window, and
  93. the y value is the number of pixels from the top.
  94. So this label starts 20 pixels in and 20 pixels down.
  95. Now make book_entry, an entry box with width equals 15.
  96. Place it at x equals 120, y equals 20.
  97. It has the same y value as the label, so it sits on the same line, and starting at
  98. 120 pixels leaves room for the label text.
  99. Make return_button, a button with the text "Return book".
  100. Place it at x equals 120, y equals 60.
  101. The x value matches the entry box, so the button lines up under it, and 60 pixels
  102. down puts it on the next line.
  103. Type window.mainloop, with brackets, at the end.
  104. Click File, then Save As, save the file as place_layout.py,
  105. and press F5 to run it. You see "Book number" at the top left, the entry box
  106. beside it, and the "Return book" button under the entry box.
  107. Now see what goes wrong. Close the window and change the label text to "Library book
  108. number". Run it again. The longer label now runs under the entry box.
  109. Place puts each widget exactly where you told it to, and it does not move anything
  110. out of the way.
  111. Change the text back to "Book number".
  112. This time change the geometry to, in speech marks, 200x60, and run it again.
  113. The entry box is cut off on the right, and the button is not shown at all, because
  114. 60 pixels down is now outside the window.
  115. Place does not shrink or move widgets to fit.
  116. So use place only for small, fixed windows where nothing will change size.
  117. Pack and grid work out the layout for you and adjust when text or windows change, so
  118. they are usually the better choice.
  119. Your turn. Put the geometry back to 300x150, add a label
  120. with the text "Due back" at x equals 20, y equals 100, then
  121. lengthen its text to "Date the book is due back" and run it to see whether anything
  122. overlaps.
  123. Part 4. Frames. You will group widgets inside frames to build a tidy form.
  124. Open IDLE, click File, then New File.
  125. Type import tkinter as tk, make the window, and give it the title "Parent
  126. Contact".
  127. A frame is a box that holds other widgets.
  128. Make heading_frame equals tk.Frame, and in the brackets put
  129. window. Pack it with pady equals 10.
  130. Now make heading_label with the text "Parent Contact Details" in Arial,
  131. size 14. The key change is the first thing in the brackets.
  132. Instead of window, type heading frame.
  133. That puts the label inside the frame rather than straight in the window.
  134. Then pack the label.
  135. Next, make form_frame, a frame in the window.
  136. In the brackets add b d equals 2 and relief equals, in speech marks, groove.
  137. That gives the frame a grooved border 2 pixels wide.
  138. Then add padx equals 10 and pady equals 10, which leaves space inside the border.
  139. Pack the form frame with padx equals 10.
  140. Now fill the form frame. Make the "Child name", "Parent name" and "Phone" labels,
  141. each with form frame as the first thing in the brackets, and an entry box beside
  142. each one. Lay them out with grid.
  143. The labels go in column 0 with sticky equals e, and the boxes go in column 1,
  144. in rows 0, 1 and 2. Rows and columns now count from the top left of the frame, not
  145. the window, so the first row inside the frame is row 0.
  146. Make button_frame, another frame in the window, and pack it with pady equals 10 so
  147. it sits under the form.
  148. Put the "Save" and "Clear" buttons in button frame.
  149. Pack each one with side equals, in speech marks, left, and padx equals
  150. 5, so they sit side by side. These buttons do nothing yet, because this video is
  151. about layout.
  152. Type window.mainloop, with brackets, at the end.
  153. Click File, then Save As, save the file as frames.py, and press F5 to run
  154. it.
  155. The "Parent Contact" window has 3 parts.
  156. The heading "Parent Contact Details" is at the top.
  157. Under it is a box with a grooved border holding the "Child name", "Parent name" and
  158. "Phone" labels, with an entry box beside each.
  159. At the bottom, the "Save" and "Clear" buttons sit side by side.
  160. Notice that the window itself uses pack, and form frame uses grid.
  161. You can use a different layout in each frame.
  162. But never mix pack and grid in the same frame, because they fight over where things
  163. go.
  164. Your turn. Add an "Email" label and entry box to form frame in row 3, using grid,
  165. then add a third button with the text "Close" to button frame, packed on the left,
  166. and run it to check the layout stays tidy.
  167. That's Tkinter layout done. You stacked widgets with pack, lined up a form with
  168. grid, saw where place goes wrong, and grouped widgets inside frames.
  169. If you skipped any of the 4 tasks, go back to the end of that part and have a go.
  170. Next, watch the next video on screen, or pick another topic from the playlist.