Evgenii Legotckoi
Evgenii Legotckoi10 листопада 2015 р. 08:06

QML - Урок 013. Позиціонування за допомогою якорів

Крім традиційних Grid, Row, Column, Qt Quick також надає функціонал для елементів шарів, що використовує концепцію якорів ( Anchors ). Кожен елемент може бути розглянутий як має набір з 7 невидимих "якорних ліній":

  • left;
  • horizontalCenter;
  • right;
  • top;
  • verticalCenter;
  • baseline;
  • bottom.

Baseline (на даному малюнку) відповідає уявлюваної лінії, де міститься текст. Для елементів без тексту це відповідає лінії top.


Система якорів Qt Quick дозволяє визначати взаємовідносини між якірними лініями різних елементів. Наприклад, Ви можете написати:

Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; ... }

У цьому випадку, ліва сторона rect2 буде пов'язана з правою стороною rect1, і виглядатиме так:

Ви можете вказати кілька якорів. Наприклад:

Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ... }

Вказуючи кілька горизонтальних або вертикальних якорів, можна контролювати розмір елемента. На малюнку нижче, rect2 пов'язаний якорем з rect1 з правого боку та з rect3 з лівого боку. Якщо якийсь із синіх прямокутників пересунути, то rect2 розтягнеться або стиснеться відповідно:

Є також деякий зручний функціонал якорів, наприклад, anchors.fill, котрий встановлює left, right, top та bottom якоря до цільового елементу. anchors.centerIn аналогічний використанню verticalCenter та horizontalCenter одночасно щодо цільового елемента. Тобто встановлює інший елемент центру цільового елемента.

Anchors Margins (Поля) та Offsets (зміщення)

Система якорів також дозволяє встановлювати поля та зміщення для зазначених якорів елементів. Поля вказують порожній простір, який має бути між якорною лінією та елементом, тоді як зсув дозволяє керувати позиціонуванням за допомогою центру якірних ліній. Елемент може вказати поля індивідуально для кожного якоря через leftMargin, rightMargin, topMargin, bottomMargin або використовувати anchors.margins для вказівки значення поля для всіх чотирьох сторін. Зміщення якоря вказуються використанням horizontalCenterOffset, verticalCenterOffset та baselineOffset.**

Наступний приклад вказує left margin:

Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }

У цьому випадку поле складає 5 пікселів ліворуч від rect2:

Примітка: Поля якорів використовуються тільки для якорів, вони не використовуються стосовно елементів. Тобто, якщо вказано поле (margin) для певної сторони, але елемент не прив'язаний якорем до сторони будь-якого елемента, то поле не застосовується.

Зміна Anchors

Qt Quick надає тип AnchorChanges для уточнення стану якоря.

State {
    name: "anchorRight"
    AnchorChanges {
        target: rect2
        anchors.right: parent.right
        anchors.left: undefined  //remove the left anchor
    }
}

AnchorChanges може бути анімований, використовуючи тип AnchorAnimation.

Transition {
    AnchorAnimation {}  //animates any AnchorChanges in the corresponding state change
}

Якорі також можуть бути змінені безпосередньо за допомогою JavaScript. Однак ці зміни повинні бути здійснені обережно, оскільки можуть призвести до непередбачуваних результатів. Наступний приклад ілюструє проблему:

//bad code
    Rectangle {
        width: 50
        anchors.left: parent.left

        function reanchorToRight() {
            anchors.right = parent.right
            anchors.left = undefined
        }
    }

У прикладі на початку встановлюється правий якір. У той момент, коли лівий та правий якорі встановлені, елемент розтягується по горизонталі свого елемента. Коли лівий якорь видаляється, елемент отримує новий параметр ширини. У результаті параметри ширини об'єкта змінюються, тоді як необхідно зберегти задану ширину об'єкта. Для цього необхідно спочатку видалити лівий якір, а потім встановити правий якір.

 Rectangle {
    width: 50
    anchors.left: parent.left

    function reanchorToRight() {
        anchors.left = undefined
        anchors.right = parent.right
    }
}

Оскільки значення прив'язки не визначені, то не рекомендується змінювати якорі через прив'язки за умовою, оскільки це може призвести до вищезазначеної проблеми. У наступному прикладі прямокутник у результаті розтягнеться на всю ширину свого батька, тому що обидва якорі будуть встановлені одночасно протягом оновлення прив'язок.

//bad code
Rectangle {
    width: 50; height: 50
    anchors.left: state == "right" ? undefined : parent.left;
    anchors.right: state == "right" ? parent.right : undefined;
}

Цей код повинен бути переписаний через AnchorChenges, який буде проводити автоматичну обробку прив'язок якорів.

Обмеження

Для покращення продуктивності ви можете використовувати якір тільки безпосередньо до батьківського елемента або до елементів братів, тобто тих, що лежать у тому ж батьку, що і даний елемент. Наприклад, наступний код є неправильним:

//bad code
Item {
    id: group1
    Rectangle { id: rect1; ... }
}
Item {
    id: group2
    Rectangle { id: rect2; anchors.left: rect1.right; ... }    // invalid anchor!
}

Також шари засновані на якорях не можуть бути змішані з абсолютним позиціонуванням. Якщо елементу вказується його позиція і також встановлюється acnhors.left або додатково до лівого та правого якоря вказується ширина елемента, результат не буде визначений, оскільки не відомо, чи потрібно використовувати якоря або абсолютне позиціонування. Те саме можна сказати про висоту елемента та використання якорів top і bottom, або установку acnhors.fill з установкою висоти або ширини. Те саме відноситься і до встановлення таких об'єктів як Row та Grid, які можуть встановлювати елементи властивості x та y . Якщо ви хочете змінити якорне позиціонування на абсолютне, значення якоря необхідно очистити.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
d
  • dsfs
  • 26 квітня 2024 р. 14:56

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80бали,
  • Рейтинг балів4
d
  • dsfs
  • 26 квітня 2024 р. 14:45

C++ - Тест 002. Константы

  • Результат:50бали,
  • Рейтинг балів-4
d
  • dsfs
  • 26 квітня 2024 р. 14:35

C++ - Тест 001. Первая программа и типы данных

  • Результат:73бали,
  • Рейтинг балів1
Останні коментарі
k
kmssr09 лютого 2024 р. 05:43
Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко05 лютого 2024 р. 12:50
Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 грудня 2023 р. 21:30
Boost - статичне зв&#39;язування в проекті CMake під Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 грудня 2023 р. 19:38
Boost - статичне зв&#39;язування в проекті CMake під Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik19 грудня 2023 р. 08:01
Qt/C++ - Урок 056. Підключення бібліотеки Boost в Qt для компіляторів MinGW і MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Тепер обговоріть на форумі
Evgenii Legotckoi
Evgenii Legotckoi03 травня 2024 р. 00:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
IscanderChe
IscanderChe30 квітня 2024 р. 14:22
Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…
G
Gar22 квітня 2024 р. 15:46
Clipboard Как скопировать окно целиком в clipb?
Павел Дорофеев
Павел Дорофеев14 квітня 2024 р. 12:35
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
f
fastrex04 квітня 2024 р. 14:47
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

Слідкуйте за нами в соціальних мережах