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
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,>…

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