4.3. Программа, демонстрирующая размещения

Здесь находится код, использованный для создания картинок показанных выше. Он достаточно подробно прокомментирован, поэтому у вас не должно возникнуть проблем с ним. Запустите его сами, и поиграйте с ним.

  1. #!/usr/bin/env python
  2. # --*-- coding:utf-8 --*--
  3. # example packbox.py
  4.  
  5. import pygtk
  6. pygtk.require('2.0')
  7. import gtk
  8. import sys, string
  9.  
  10. # Вспомогательная функция, которая заполняет новые HBox кнопками-метками.
  11. # Значения нужных нам переменных мы передаём в эту функцию.
  12. # Мы не показываем коробку, но показываем всё внутри.
  13.  
  14. def make_box(homogeneous, spacing, expand, fill, padding):
  15.  
  16. # Создаём новый HBox с соответствующими
  17. # параметрами homogeneous и spacing.
  18. box = gtk.HBox(homogeneous, spacing)
  19.  
  20. # Создаёт набор кнопок с соответствующими настройками.
  21. button = gtk.Button("box.pack")
  22. box.pack_start(button, expand, fill, padding)
  23. button.show()
  24.  
  25. button = gtk.Button("(button,")
  26. box.pack_start(button, expand, fill, padding)
  27. button.show()
  28.  
  29. # Создаём кнопку с меткой, отражающей значение
  30. # expand.
  31. if expand == True:
  32. button = gtk.Button("True,")
  33. else:
  34. button = gtk.Button("False,")
  35.  
  36. box.pack_start(button, expand, fill, padding)
  37. button.show()
  38.  
  39. # Здесь всё похоже на создание кнопки "expand"
  40. # выше, но используется более короткая форма.
  41. button = gtk.Button(("False,", "True,")[fill==True])
  42. box.pack_start(button, expand, fill, padding)
  43. button.show()
  44.  
  45. padstr = "%d)" % padding
  46.  
  47. button = gtk.Button(padstr)
  48. box.pack_start(button, expand, fill, padding)
  49. button.show()
  50. return box
  51.  
  52. class PackBox1:
  53. def delete_event(self, widget, event, data=None):
  54. gtk.main_quit()
  55. return False
  56.  
  57. def __init__(self, which):
  58.  
  59. # Создаём наше окно
  60. self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
  61.  
  62. # Вы должны всегда помнить о подключении главного окна к сигналу
  63. # delete_event. Это очень важно для правильной
  64. # интуитивной работы.
  65. self.window.connect("delete_event", self.delete_event)
  66. self.window.set_border_width(10)
  67.  
  68. # Мы создаём вертикальную коробку, для того чтобы разместить в ней HBox
  69. # Это позволяет нам расположить HBox
  70. # одну над другой в VBox.
  71. box1 = gtk.VBox(False, 0)
  72.  
  73. # Какой пример показывать. Это соответствует картинкам выше.
  74. if which == 1:
  75. # Создаём новую метку.
  76. label = gtk.Label("HBox(False, 0)")
  77.  
  78. # Выравниваем метку по левому краю. Мы обсудим этот и
  79. # и другие методы в разделе Параметры виджетов.
  80. label.set_alignment(0, 0)
  81.  
  82. # Размещаем метку в VBox. Помните что
  83. # виджеты добавляемые в коробку будут помещены выше остальных
  84. # по порядку.
  85. box1.pack_start(label, False, False, 0)
  86.  
  87. # Показываем метку
  88. label.show()
  89.  
  90. # Вызываем функцию make_box - homogeneous = False, spacing = 0,
  91. # expand = False, fill = False, padding = 0
  92. box2 = make_box(False, 0, False, False, 0)
  93. box1.pack_start(box2, False, False, 0)
  94. box2.show()
  95.  
  96. # Вызываем функцию make_box - homogeneous = False, spacing = 0,
  97. # expand = True, fill = False, padding = 0
  98. box2 = make_box(False, 0, True, False, 0)
  99. box1.pack_start(box2, False, False, 0)
  100. box2.show()
  101.  
  102. # Параметры:: homogeneous, spacing, expand, fill, padding
  103. box2 = make_box(False, 0, True, True, 0)
  104. box1.pack_start(box2, False, False, 0)
  105. box2.show()
  106.  
  107. # Создаём разделитель. Мы рассмотрим его позже
  108. # но он очень простой.
  109. separator = gtk.HSeparator()
  110.  
  111. # Размещаем разделитель в VBox. Помните, что каждый
  112. # виджет укладываемый в VBox размещается
  113. # вертикально.
  114. box1.pack_start(separator, False, True, 5)
  115. separator.show()
  116.  
  117. # Создаём ещё одну метку и показываем её.
  118. label = gtk.Label("HBox(True, 0)")
  119. label.set_alignment(0, 0)
  120. box1.pack_start(label, False, False, 0)
  121. label.show()
  122.  
  123. # Параметры: homogeneous, spacing, expand, fill, padding
  124. box2 = make_box(True, 0, True, False, 0)
  125. box1.pack_start(box2, False, False, 0)
  126. box2.show()
  127.  
  128. # Параметры: homogeneous, spacing, expand, fill, padding
  129. box2 = make_box(True, 0, True, True, 0)
  130. box1.pack_start(box2, False, False, 0)
  131. box2.show()
  132.  
  133. # Ещё один разделитель.
  134. separator = gtk.HSeparator()
  135. # 3 последние аргумента к pack_start:
  136. # expand, fill, padding.
  137. box1.pack_start(separator, False, True, 5)
  138. separator.show()
  139. elif which == 2:
  140. # Создаём новую метку, помним что box1 это VBox
  141. # который создаётся в начале __init__()
  142. label = gtk.Label("HBox(False, 10)")
  143. label.set_alignment( 0, 0)
  144. box1.pack_start(label, False, False, 0)
  145. label.show()
  146.  
  147. # Параметры: homogeneous, spacing, expand, fill, padding
  148. box2 = make_box(False, 10, True, False, 0)
  149. box1.pack_start(box2, False, False, 0)
  150. box2.show()
  151.  
  152. # Параметры: homogeneous, spacing, expand, fill, padding
  153. box2 = make_box(False, 10, True, True, 0)
  154. box1.pack_start(box2, False, False, 0)
  155. box2.show()
  156.  
  157. separator = gtk.HSeparator()
  158. # 3 последние аргумента к pack_start:
  159. # expand, fill, padding.
  160. box1.pack_start(separator, False, True, 5)
  161. separator.show()
  162.  
  163. label = gtk.Label("HBox(False, 0)")
  164. label.set_alignment(0, 0)
  165. box1.pack_start(label, False, False, 0)
  166. label.show()
  167.  
  168. # Параметры: homogeneous, spacing, expand, fill, padding
  169. box2 = make_box(False, 0, True, False, 10)
  170. box1.pack_start(box2, False, False, 0)
  171. box2.show()
  172.  
  173. # Параметры: homogeneous, spacing, expand, fill, padding
  174. box2 = make_box(False, 0, True, True, 10)
  175. box1.pack_start(box2, False, False, 0)
  176. box2.show()
  177.  
  178. separator = gtk.HSeparator()
  179. # 3 последние аргумента к pack_start:
  180. # expand, fill, padding.
  181. box1.pack_start(separator, False, True, 5)
  182. separator.show()
  183.  
  184. elif which == 3:
  185.  
  186. # Здесь показывается возможность использования pack_end() для
  187. # помещения виджетов справа. Сначала мы создаём новую коробку как и раньше.
  188. box2 = make_box(False, 0, False, False, 0)
  189.  
  190. # Создаём метку, которую разместим вконце.
  191. label = gtk.Label("end")
  192. # Размещаем её используя pack_end(), и она будет находиться
  193. # на правой стороне HBox созданной вызовом make_box().
  194. box2.pack_end(label, False, False, 0)
  195. # Показываем метку.
  196. label.show()
  197.  
  198. # Размещаеи box2 в box1
  199. box1.pack_start(box2, False, False, 0)
  200. box2.show()
  201.  
  202. # Разделитель для низа.
  203. separator = gtk.HSeparator()
  204.  
  205. # Явным образом создаём разделитель 400 пикселей в шрину и
  206. # 5 пикселей в высоту. Созданный HBox также имеет 400
  207. # пикселей в ширину и метку "end", которая отделена от
  208. # других меток в коробке. Иначе, все виджеты в коробке
  209. # будут помещены вплотную друг к другу.
  210. separator.set_size_request(400, 5)
  211. # Помещаем в коробку разделитель созданный вначале.
  212. # метода __init__()
  213. box1.pack_start(separator, False, True, 5)
  214. separator.show()
  215.  
  216. # Создаём ещё один HBox... помните что мы можем использовать их столько сколько нужно!
  217. quitbox = gtk.HBox(False, 0)
  218.  
  219. # Наша кнопка выхода.
  220. button = gtk.Button("Выход")
  221.  
  222. # Настраиваем сигнал для завершения программы по нажатию кнопки
  223. button.connect("clicked", lambda w: gtk.main_quit())
  224. # Размещаем коробку в quitbox.
  225. # 3 последние аргумента к pack_start:
  226. # expand, fill, padding.
  227. quitbox.pack_start(button, True, False, 0)
  228. # Размещаем quitbox в vbox (box1)
  229. box1.pack_start(quitbox, False, False, 0)
  230.  
  231. # Размещаем VBox (box1) который содержит все наши виджеты в
  232. # главное окно.
  233. self.window.add(box1)
  234.  
  235. # И показываем всё что осталось
  236. button.show()
  237. quitbox.show()
  238.  
  239. box1.show()
  240. # Показываем окно в посленюю очередь
  241. self.window.show()
  242.  
  243. def main():
  244. # И конечно наш основной цикл.
  245. gtk.main()
  246. # Управление перейдёт сюда после вызова main_quit()
  247. return 0
  248.  
  249. if __name__ =="__main__":
  250. sys.argv.append('1')
  251. if len(sys.argv) != 2:
  252. sys.stderr.write("Использование: packbox.py num, где num это 1, 2, или 3.\n")
  253. sys.exit(1)
  254. PackBox1(string.atoi(sys.argv[1]))
  255. main()
  256.  

Короткое объяснение packbox.py начинается со строк 14-50 которые определяют вспомогательную функцию make_box(), которая создаёт горизонтальную коробку и заполняет её кнопками. Она возвращает ссылку на HBox.

Строки 52-241 определяют конструктор __init__() класса PackBox1 который создаёт окно и VBox, который заполняет окно различными виджетами, зависящими от передаваемых аргументов. Если передаётся 1, строки 75-138 создают окно, отображающее 5 уникальных вариантов размещения, получаемых изменением параметров homogeneous, expand и fill. Если передаётся 2, строки 140-182 создают окно, отображающее различные комбинации заполнения по параметрам spacing и padding. Наконец, если передаётся 3, то строки 188-214 создают окно, отображающее использование методов pack_start() и pack_end() для размещения на разных сторонах. Строки 215-235 создают горизонтальную коробку, содержащую кнопку, которая размещена в VBox. Сигнал "clicked" подключен к функции PyGTK main_quit() для завершения программы.

Строки 251-253 проверяют аргументы командной строки, и выходят из программы используя функцию sys.exit() если не передано ни одного аргумента. Строка 254 создаёт экземпляр PackBox1. Строка 255 вызывает функцию main() для начала цикла обработки событий GTK+.

Заметьте, что в этом примере ссылки на различные виджеты (кроме окна) не сохраняются (последовательно используется одно и тоже имя переменной для различных объектов), поскольку в дальнейшем они нам не нужны.