Публикации Lazarus

Использование редактора привязок в Lazarus

17.02.2009
Лагунов А.А.

Перед разработчиками интерфейсов очень часто в полный рост встаёт проблема размещения элементов управления на формах. Суть проблемы в следующем — тема интерфейса у разработчика и конечного пользователя его продукта очень часто может не совпадать. Особенно актуально это в свете применения Lazarus — когда не только тема оформления, но и сама операционная система может быть различной. В итоге, то что разработчик кропотливо расставлял элементы управления и наводил красоту на форму, ещё не гарантирует — что эта форма будет также выглядеть у оператора.

Например: простейшая форма — нарисованная в Lazarus под Windows и то, как она выглядит в Linux-е (GTK2, тема элементов — ClearLooks)).


Вид формы в Windows


Вид формы в Linux

Сразу бросается в глаза, то что на кнопках текст отображается не верно, высота полей ввода не соответствует высоте текста, введённого в этих полях.

Для решения этой проблемы в Lazarus и LCL введены специальные свойства для элементов управления.

  1. Практически все визуальные элементы имеют свойство AutoSize.
  2. У всех визуальных элементов на свойство Anchors включён редактор привязок, этот же редактор можно вызвать из главного меню IDE - «Вид/Показывать редактор привязок».

С помощью этих средств можно добиться того, чтобы, вне зависимости от того, как пользователь настроил себе тему интерфейса рабочего стола, программа выглядела так, как задумал автор. При этом программа не будет белой вороной среди других программ у оператора.

Немного теории:

При изменении темы интерфейса меняется размер (высота) шрифта — и этот фактор является основным, который «корёжит» внешний вид.

При включённом свойстве AutoSize компонент рассчитывает свою высоту в зависимости от текущего шрифта для наилучшего отображения текста. Ширина, при включённом AutoSize, меняется только у тех компонент, для которых это критично — например TLabel, Tbutton (и его наследники). Для полей ввода, списков, таблиц — ширина автоматически не меняется. Для TBitBtn (кнопка с изображением) верно ещё одно замечание — её высота также рассчитывается от высоты изображения, нарисованного на кнопке.

Таким образом — правильный размер визуальных элементов обеспечит свойство AutoSize.

Но остаётся ещё проблема промежутков между элементами. Если промежутки не менять, то может получиться ситуация, когда из-за увеличения размера элемента, он может «наползти» на другой элемент.

Для контроля зазоров нам необходимо свойство Anchors, вернее его редактор.

Несмотря на устрашающий вид, смысл формы прост. В ней задаются элементы, с которой граничит наш выбранный элемент управления и промежутки между границами. Также здесь определяется тип границы.

Конкретно на данном рисунке показаны настройки для элемента Label3 — метка с текстом «Место».

В окне редактора привязок находится 4 группы элементов управления (логических), которые отвечают за 4 границы нашего редактируемого визуального компонента — верхняя, нижняя граница, левая и правая. Флажок «Включить» в каждой из групп обозначает то, что визуальный контроль будет отслеживать во время работы программы свою соответствующую границу. Если в выпадающем списке ничего не выбрано — этот флажок фактически просто соответствует свойству Anchors — akTop, akLeft, akRight, akBottom. Это будет стандартное поведение, которое пришло по наследству из Delphi.

Если же в выпадающем списке выбран контрол-сосед — то поведение меняется. Теперь визуальный контрол будет всегда отслеживать положение указанного соседа и располагать свои границы в зависимости от того, где кончается (или начинается) соседний контрол. Также в игру тут вступают поля «Зазоры» - с помощью их мы можем определить зазоры между котролом и его соседом, к которому осуществлена привязка. Тип привязки определяется 3-мя кнопками, которые расположены правее выпадающего списка выбора соседа.

При таких настройках контрол уже не обращает внимания на то, куда его положил разработчик во время проектирования формы — он будет руководствоваться только информацией о привязке. Согласно рекомендациям из руководства по разработке интерфейсов от авторов Gnome — зазор между соседними элементами лучше всего ставить в 6 точек. В своих программах я стараюсь придерживаться этого правила.

Теперь подробнее рассмотрим на примере

Привяжем метки и строки ввода в той последовательности, в которой они указаны на рисунке. Для этого у всех элементов (3 метки, 3 строки ввода и 1 RadioGroup1 — для CheckGroup1 будут отдельные действия) выставим общий зазор 6 точек. Это делается через центральный SpinEdit у редактора привязок. Он просто упрощает операцию указания зазоров со всех сторон (вокруг). Можно то же самое сделать и просто указав зазор в 6 точек во всех 4-х полях.

Потом поставим у верхних меток (Label1 и Label2) верхнюю привязку к верхнему краю нашей разрабатываемой формы. Для наших меток мы определяем «Привязка к верхней части соседа, сохранять зазор». После этого метки будут всегда прижаты к верху формы с зазором в 6 точек.

Потом для Label1 указываем левую привязку — также форма, тип привязки — «Привязка к левой части соседа, сохранять зазор». Только эти две метки имеют верхний тип привязки «Привязка к верхней части соседа, сохранять зазор». У всех остальных необходимо сразу поставить тип верхней привязки - «Привязка к нижней части соседа, сохранять зазор».

Далее следует Edit1 — у него установим левого соседа метку Label1, тип левой привязки - «Привязка к левой части соседа, сохранять зазор». Наше поле ввода сразу переместится под метку и чуть правее. К полю ввода Edit1 привяжем левую границу метки Label2 — это необходимо для того чтобы верхние поля и метки шли друг за другом. Edit 2 привяжем к Label2 полностью аналогично как Edit1 к Label1. Дополнительно у Edit 2 установим привязку правой границы к правой границе формы. Для этого включим соответствующий переключатель, установим правого соседа — нашу форму, тип привязки — «Привязка к правой части соседа, сохранять зазор».

С Label 3 и Edit3 поступаем аналогично — слева привяжем метку к левой части окна, потом привяжем к левой границе метке поле ввода. Метку привяжем к нижней части Edit1. В конце привязываем Edit3 правую границу к правой границе окна.

RadioGroup1 — привяжем к левой границе окна и нижней части Edit3.

А вот чуть более сложная ситуация:

На разрабатываемой форме рядом находятся 2 сложных элемента: объект CheckGroup1 типа TcheckGroup и RadioGroup1 типа TradioGroup. Сложность заключается в том, что в RadioGroup1 находится 4 элемента, а в CheckGroup1 — 3 элемента. При установке у обоих объектов свойства AutoSize = true — размер CheckGroup1 будет меньше, чем размер RadioGroup1. Вот для исправления этой ситуации мы не будем устанавливать авторазмер у CheckGroup1, а осуществим привязку размеров жёстко к набору RadioGroup1 — его размер по высоте всегда будет больше. Пример этой привязки приведён на рисунке. Правая граница CheckGroup1 будет привязана к правой границе окна с отступом в 6 точек. При изменении размеров окно — группа будет растягиваться.

В итоге у нас получилось:


Итоговый вид в Windows


Итоговой вид в Linux

И в окончании 3 совета:

  1. Не нужно фиксировать размер диалоговых окон. Выставлять BorderStyle:=bsDialog — дурной тон. Пример тому, интерфейс Windows, где такое поведение встречается постоянно. Оставьте возможность пользователю менять размер диалогового окна. Тем более, что с использованием приведённых выше методик, изменение размера как раз может дать увеличение читабельности информации в диалоговом окне.
  2. Вместо отдельных кнопок OK, Cancel — используйте элемент TButtonPanel. Он даёт гарантию того, что стандартные кнопки будут расположены в соответствии с соглашениями, принятыми в данной ОС и рабочем столе, автоматически выставит размеры кнопок.
  3. Не нужно использовать не стандартные цветовые решения. Иначе при малейшем отклонении темы рабочего стола оператора от стандартного — ваша программа превратиться в настоящий павлиний хвост, который будет вносить дисгармонию в жизнь простых операторов.

В приложенном архиве находится исходный текст примера.

Актуальные версии
FPC3.2.2release
Lazarus3.2release
MSE5.10.0release
fpGUI1.4.1release
links