9.7. Линейки

Виджеты Ruler используются для отображения положения указателя мыши в окне так, как это сделано в GIMP. Окно может иметь горизонтальную линейку, размещённую от края до края и вертикальную линейку, размещённую сверху вниз. Маленький треугольный индикатор на линейке показывает положение указателя относительно линейки.

Горизонтальные и вертикальные линейки создаются с помощью функций:

  hruler = gtk.HRuler()    # горизонтальная линейка

vruler = gtk.VRuler() # вертикальная линейка

Когда линейка создана, мы можем определить единицу измерения. Единицами могут быть PIXELS, INCHES или CENTIMETERS. Они устанавливаются с помощью метода:

  ruler.set_metric(metric)

По умолчанию используется PIXELS.

  ruler.set_metric(gtk.PIXELS)

Другой важной характеристикой линейки является то, как отмечать единицы шкалы, и положение индикатора по умолчанию. Для установки используется метод:

  ruler.set_range(lower, upper, position, max_size)

Аргументы lower и upper определяют размер линейки, и max_size  - самое большое отображаемое число. Position определяет позицию индикатора по умолчанию.

Вертикальная линейка может охватить окно в 800 пикселей следующим образом:

  vruler.set_range(0, 800, 0, 800)

Отметки отображаются на линейке от 0 до 800, с числом для каждого сотого пикселя. Если нам нужна линейка для диапазона от 7 до 16:

  vruler.set_range(7, 16, 0, 20)

Индикатор на линейке это маленькая треугольная метка. Если линейка используется для следования за курором мыши, сигнал "motion_notify_event" должен быть подключен к методу "motion_notify_event" линейки. Нам нужно настроить callback-функцию для "motion_notify_event" и использовать connect_object() для того, чтобы позволить линейке излучать "motion_notify_signal":

def motion_notify(ruler, event):
return ruler.emit("motion_notify_event", event)
 
area.connect_object("motion_notify_event", motion_notify, ruler)

Пример rulers.py создаёт область для рисования с горизонтальной линейкой сверху и вертикальной линейкой слева. Размер области: 600 пикселей в ширину и 400 в высоту. Горизонтальная линейка измеряет от 7 до 13, с отметкой каждые 100 пикселей, когда вертикальная измеряет от 0 до 400 с отметкой каждые 100 пикселей. Расположение области рисования и линеек выполнено с помощью таблицы. Рисунок 9.8, “Пример линеек” показывает получаемое окно:

Рисунок 9.8. Пример линеек

Rulers Example

Исходный код rulers.py:

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. # example rulers.py
  4.  
  5. import pygtk
  6. pygtk.require('2.0')
  7. import gtk
  8.  
  9. class RulersExample:
  10. XSIZE = 400
  11. YSIZE = 400
  12.  
  13. # Этот шаблон получает управление при клике на кнопку закрытия
  14. def close_application(self, widget, event, data=None):
  15. gtk.main_quit()
  16. return False
  17.  
  18. def __init__(self):
  19. window = gtk.Window(gtk.WINDOW_TOPLEVEL)
  20. window.connect("delete_event", self.close_application)
  21. window.set_border_width(10)
  22.  
  23. # Создаём таблицу для размещения линеек и области рисования
  24. table = gtk.Table(3, 2, False)
  25. window.add(table)
  26.  
  27. area = gtk.DrawingArea()
  28. area.set_size_request(self.XSIZE, self.YSIZE)
  29. table.attach(area, 1, 2, 1, 2,
  30. gtk.EXPAND|gtk.FILL, gtk.FILL, 0, 0 )
  31. area.set_events(gtk.gdk.POINTER_MOTION_MASK |
  32. gtk.gdk.POINTER_MOTION_HINT_MASK )
  33.  
  34. # Горизонтальная линейка наверху. Когда курсор проходит по
  35. # области рисования, motion_notify_event передаётся
  36. # в подходящий обработчик для линейки.
  37. hrule = gtk.HRuler()
  38. hrule.set_metric(gtk.PIXELS)
  39. hrule.set_range(7, 13, 0, 20)
  40. def motion_notify(ruler, event):
  41. return ruler.emit("motion_notify_event", event)
  42. area.connect_object("motion_notify_event", motion_notify, hrule)
  43. table.attach(hrule, 1, 2, 0, 1,
  44. gtk.EXPAND|gtk.SHRINK|gtk.FILL, gtk.FILL, 0, 0 )
  45.  
  46. # Вертикальная линейка слева. При движении мыши
  47. # по области рисования motion_notify_event передаётся
  48. # в подходящий обработчик для линейки
  49. vrule = gtk.VRuler()
  50. vrule.set_metric(gtk.PIXELS)
  51. vrule.set_range(0, self.YSIZE, 10, self.YSIZE)
  52. area.connect_object("motion_notify_event", motion_notify, vrule)
  53. table.attach(vrule, 0, 1, 1, 2,
  54. gtk.FILL, gtk.EXPAND|gtk.SHRINK|gtk.FILL, 0, 0 )
  55.  
  56. # Теперь показываем всё
  57. area.show()
  58. hrule.show()
  59. vrule.show()
  60. table.show()
  61. window.show()
  62.  
  63. def main():
  64. gtk.main()
  65. return 0
  66.  
  67. if __name__ == "__main__":
  68. RulersExample()
  69. main()
  70.  

Строки 42 и 52 подключают callback-функцию motion_notify() к области, и передают hrule в строке 42 и vrule в строке 52 как пользовательские данные. Функция motion_notify() будет вызываться дважды при движении мыши, один раз с hrule и c vrule.