mafulechka
mafulechka18 березня 2020 р. 06:01

Користувальницькі оформлення вікон на стороні клієнта Qt 5.15

Це свіжі новини про нову функцію в Qt 5.15, яка дуже порадувала.

Зазвичай оформлення вікон були досить нудною річчю. Заголовок, обмежити, мінімізувати, максимізувати, змінити розмір, вийти... і все.


Однак, останнім часом програми все частіше і частіше включають інтерфейс користувача (application specific UI) і оформлення тем. Пара скріншотів для пояснення, про що тут йдеться:

MacOS займається цим досить давно.

... і Chrome, і будь-який інший веб-браузер.

Вбудовування меню в оформлення може заощадити багато місця на екрані.

... або це може бути важливим для брендингу або дизайну.
На жаль, подібні речі раніше не були можливі з Qt.
Однак можна було прибрати оформлення з вікна, тобто:

Window {
    flags: Qt.FramelessWindowHint
}

Але це тільки залишило вас із вікном без оформлення. Таким чином, це не могло бути переміщене або змінене. Якщо б ви спробували реалізувати рух вікна або змінити розмір, схопивши мишу і вручну встановивши розмір і положення вікна, ви швидко виявили б, що це не дуже добре. Менеджери вікон зазвичай мають дуже специфічну поведінку при переміщенні або зміні розмірів вікон. Звичайні дії: перетягування вгору, щоб максимізувати, перетягування ліворуч/праворуч на плитку, прив'язка до інших вікон або панелі завдань, зміна розмірів двох вікон одночасно, якщо вони розташовані поруч один з одним і так далі.

Заради справедливості, раніше був наданий один помічник - QSizeGrip. Він дозволяє змінити розмір будь-якого заданого кута вікна, але працює тільки з кутами, а не з межами вікна, і доступний тільки для програм віджетів.

У Qt 5.15 було додано два нових методи QWindow: startSystemMove і startSystemResize. Ці методи просять віконний менеджер вступити у володіння та розпочати власну операцію зміни розміру чи переміщення. Це означає, що прив'язка, розбиття на тайли і так далі повинні працювати просто чарівним чином, а реалізація заголовка в QML стає майже однорядковою:

DragHandler {
    onActiveChanged: if (active) window.startSystemMove();
    target: null
}

Помістивши цей фрагмент коду елемент QtQuick, всі тригер операції перетягування викличуть операцію переміщення власного вікна.
startSystemResize працює аналогічно, за винятком того, що він приймає аргумент Qt::Edges, який є бітовим полем меж вікна, які ви захопили, тобто для нижнього правого кута, ви б викликали:

startSystemResize(Qt.RightEdge | Qt.BottomEdge)

Це також дуже зручно, так як ви можете легко мати один обробник для всіх чотирьох меж вікна і просто створити аргумент кордону наступним чином:

DragHandler {
    id: resizeHandler
    grabPermissions: TapHandler.TakeOverForbidden
    target: null
    onActiveChanged: if (active) {
        const p = resizeHandler.centroid.position;
        let e = 0;
        if (p.x < border) e |= Qt.LeftEdge;
        if (p.x >= width - border) e |= Qt.RightEdge;
        if (p.y < border) e |= Qt.TopEdge;
        if (p.y >= height - border) e |= Qt.BottomEdge;
        window.startSystemResize(e);
    }
}

Якщо ви хочете отримати повний приклад того, як це можна використовувати, було зроблено макет браузера з використанням нового API.

Зверніть увагу, що, хоча це кроссплатформенний API, не всі платформи підтримують його. startSystemMove в даний час підтримується в Wayland, X11, macOS і Windows, а startSystemResize, з іншого боку, підтримується в Wayland, X11 і Windows, але не в macOS.

Щоб упоратися з цим, обидва методи повертають логічне значення, яке вказує, чи була операція підтримана чи ні. Це означає, що якщо ви хочете реалізувати зміну розміру і в macOS, вам доведеться перевірити значення startSystemResize, що повертається, і постаратися зробити все можливе, щоб реалізувати запасний варіант у разі збою, тобто:

if (!window.startSystemResize(edges)) {
    // your fallback code for setting window.width/height manually
}

Подальша робота в Qt буде полягати в тому, щоб надати запасні варіанти або абстракції, які зробили б цю роботу за вас, але, принаймні, ніщо не повинно завадити вам зробити це самостійно.

Інша область покращення - узгодження з віконним менеджером у тому, чи слід використовувати оформлення на стороні клієнта або сервері. Деякі програми можуть захотіти підтримувати обидва режими і дозволити віконному менеджеру вирішувати, але це неможливо. Після встановлення FramelessWindowHint оформлення на стороні сервера не буде.

Третя область – тінь вікна. Принаймні на Wayland тінь має бути намальована як частина оформлення вікна. І хоча можна малювати тіні за допомогою QtQuick, в даний час немає способу повідомити плагін QPA, яка частина поверхні є тінню, а яка - віконною рамкою, що означає, що, якщо ви спробуєте намалювати тіні, менеджер вікон в даний час буде розглянути тіньову частину вікна, і це зіпсує мозаїку та прив'язку з іншими вікнами. На інших платформах диспетчер вікон зазвичай малює тіні навіть для вікон, оформлених на стороні клієнта, тому цю проблему складно вирішити.

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

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

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
AD

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

  • Результат:50бали,
  • Рейтинг балів-4
m
  • molni99
  • 26 жовтня 2024 р. 01:37

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

  • Результат:80бали,
  • Рейтинг балів4
m
  • molni99
  • 26 жовтня 2024 р. 01:29

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

  • Результат:20бали,
  • Рейтинг балів-10
Останні коментарі
ИМ
Игорь Максимов22 листопада 2024 р. 11:51
Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii Legotckoi31 жовтня 2024 р. 14:37
Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZE19 жовтня 2024 р. 08:19
Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов05 жовтня 2024 р. 07:51
Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas505 липня 2024 р. 11:02
QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Тепер обговоріть на форумі
Evgenii Legotckoi
Evgenii Legotckoi24 червня 2024 р. 15:11
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey115 листопада 2024 р. 06:04
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProject04 червня 2022 р. 03:49
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9Anonim25 жовтня 2024 р. 09:10
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

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