Evgenii Legotckoi
Evgenii Legotckoi25 листопада 2019 р. 15:35

QML - Урок 038. Використання властивості clip для обрізання child об'єктів всередині Item або Rectangle

Досить часто на форумі виникає одне і те ж питання, який стосується проблеми відображення контенту, вкладеного в будь-які об'єкти QML.

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

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

  • Ліве вікно показує, як виглядає верстка спочатку
  • Права вікно показує, що якщо почати гортати контент ListView, то він буде заходити під текст Title, хоча мав би обрізатися.


Початковий приклад коду

Ось так виглядає початковий програмний код.

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Text {
        id: topText
        text: qsTr("Title")

        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: parent.top
    }

    ListView {
        width: 180; height: 200

        model: contactModel
        delegate: Text {
            text: name + ": " + number
        }

        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: topText.bottom
    }

    ListModel {
        id: contactModel
        ListElement {
            name: "Bill Smith"
            number: "555 3264"
        }
        ListElement {
            name: "John Brown"
            number: "555 8426"
        }
        ListElement {
            name: "Sam Wise"
            number: "555 0473"
        }
    }
}

Щоб вирішити дану проблему, досить встановити властивість clip: true у ListView .

ListView {
    clip: true

    /* код */
}

І тепер контент ListView не виходитиме за межі ListView

Використання у Rectangle об'єктів

Аналогічним чином clip працює і для Rectangle об'єктів Ось програмний код, а також приклад до і після включення clip.

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Rectangle {
        x: 27
        y: 31
        width: 100
        height: 100
        color: "blue"https://evileg.com/ru/knowledge/article/577/change/#
        clip: true

        Rectangle {
            x: -20
            y: -20
            width: 100
            height: 100

            color: "green"
        }
    }
}

Закруглення країв

А ось, що не працює при використанні clip, так це закруглення країв, навіть якщо налаштовуватися радіус закруглення країв у батьківського Rectangle об'єкта.

Наприклад у нас ось такий код не дасть очікуваного результату

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Rectangle {
        x: 27
        y: 31
        width: 100
        height: 100
        color: "blue"
        radius: 30 // встановили закруглення
        clip: true // включили обрізку

        Rectangle {
            x: -20
            y: -20
            width: 100
            height: 100

            color: "green"
        }
    }
}

Отриманний результат

Така поведінка clip є стандартним і зроблено було так з міркувань продуктивності, оскільки практично всі графічні елементи QML успадковуються від типу Item. А значить додаткова обробка масок у всьому додатку є надмірною.

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

import QtQuick 2.12
import QtQuick.Window 2.12
import QtGraphicalEffects 1.13

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Rectangle {
        id: rect
        x: 27
        y: 31
        width: 100
        height: 100
        color: "blue"

        layer.enabled: true
        layer.effect: OpacityMask {
            maskSource: Item {
                width: rect.width
                height: rect.height
                Rectangle {
                    anchors.centerIn: parent
                    width: rect.adapt ? rect.width : Math.min(rect.width, rect.height)
                    height: rect.adapt ? rect.height : width
                    radius: 30
                }
            }
        }

        Rectangle {
            x: -20
            y: -20
            width: 100
            height: 100

            color: "green"
        }
    }
}

А результат буде таким

Висновок

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

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

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

f
  • 21 жовтня 2021 р. 05:24

Зачем внутри OpacityMask Item, почему сразу Rectangle не вставить?
И что за rect.adapt?

Мое предложение:

        layer.enabled: true
        layer.effect: OpacityMask {
            maskSource: Rectangle {
                width: rect.width
                height: rect.height
                radius: 30
            }
        }

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
Дмитрий

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

  • Результат:60бали,
  • Рейтинг балів-1
Дмитрий

C++ - Тест 003. Условия и циклы

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

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

  • Результат:80бали,
  • Рейтинг балів4
Останні коментарі
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" она решит проблему , лично мне помогло.
Тепер обговоріть на форумі
G
George1307 травня 2024 р. 10:27
добавить qlineseries в функции в функции: "GPlotter::addSeries(QString title, QVector &arr)" я вызываю метод setChart(...), я в конструктор передал адрес на QChartView элемент
BlinCT
BlinCT05 травня 2024 р. 15:46
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
PS
Peter Son04 травня 2024 р. 03:57
Best Indian Food Restaurant In Cincinnati OH Ready to embark on a gastronomic journey like no other? Join us at App india restaurant and discover why we're renowned as the Best Indian Food Restaurant In Cincinnati OH . Whether y…
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_…

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