Evgenii Legotckoi
Nov. 26, 2019, 2:35 a.m.

QML - Tutorial 038. Using the clip property to crop child objects inside Item or Rectangle

Quite often, the same question arises on the forum regarding the problem of displaying content embedded in any QML objects.

The most common manifestation of this problem is when ListView content scrolls beyond its scope. In any case, this is one of those frequent cases when beginners encounter this problem when starting to learn QML. Well, or another option when faced with such a problem when using Rectangle objects.

In the following image below, you can see two application windows that illustrate this problem.

  • The left window shows what the layout looks like initially
  • The right window shows that if you start scrolling through ListView content, it will go under the Title text, although it should have been cropped.


Initial code example

This is what the original program code looks like.

  1. import QtQuick 2.12
  2. import QtQuick.Window 2.12
  3.  
  4. Window {
  5. visible: true
  6. width: 640
  7. height: 480
  8. title: qsTr("Hello World")
  9.  
  10. Text {
  11. id: topText
  12. text: qsTr("Title")
  13.  
  14. anchors.horizontalCenter: parent.horizontalCenter
  15. anchors.top: parent.top
  16. }
  17.  
  18. ListView {
  19. width: 180; height: 200
  20.  
  21. model: contactModel
  22. delegate: Text {
  23. text: name + ": " + number
  24. }
  25.  
  26. anchors.horizontalCenter: parent.horizontalCenter
  27. anchors.top: topText.bottom
  28. }
  29.  
  30. ListModel {
  31. id: contactModel
  32. ListElement {
  33. name: "Bill Smith"
  34. number: "555 3264"
  35. }
  36. ListElement {
  37. name: "John Brown"
  38. number: "555 8426"
  39. }
  40. ListElement {
  41. name: "Sam Wise"
  42. number: "555 0473"
  43. }
  44. }
  45. }
  46.  

To solve this problem, just set the clip: true property of ListView .

  1. ListView {
  2. clip: true
  3.  
  4. /* код */
  5. }

And now ListView content will not go beyond ListView

Using Rectangle Objects

Similarly, clip works for Rectangle objects. Here is the program code, as well as an example before and after including clip.

  1. import QtQuick 2.12
  2. import QtQuick.Window 2.12
  3.  
  4. Window {
  5. visible: true
  6. width: 640
  7. height: 480
  8. title: qsTr("Hello World")
  9.  
  10. Rectangle {
  11. x: 27
  12. y: 31
  13. width: 100
  14. height: 100
  15. color: "blue"
  16. clip: true
  17.  
  18. Rectangle {
  19. x: -20
  20. y: -20
  21. width: 100
  22. height: 100
  23.  
  24. color: "green"
  25. }
  26. }
  27. }

Rounding

But what does not work when using clip is rounding, even if you adjust the radius of rounding at the parent Rectangle object.

For example, here we have such a code will not give the expected result

  1. import QtQuick 2.12
  2. import QtQuick.Window 2.12
  3.  
  4. Window {
  5. visible: true
  6. width: 640
  7. height: 480
  8. title: qsTr("Hello World")
  9.  
  10. Rectangle {
  11. x: 27
  12. y: 31
  13. width: 100
  14. height: 100
  15. color: "blue"
  16. radius: 30 // set rounding
  17. clip: true // enable cropping
  18.  
  19. Rectangle {
  20. x: -20
  21. y: -20
  22. width: 100
  23. height: 100
  24.  
  25. color: "green"
  26. }
  27. }
  28. }
  29.  

The result

This clip behavior is standard and has been done for performance reasons, since almost all QML graphic elements are inherited from the Item type. This means that additional processing of masks throughout the application is redundant.

But the expected result can be achieved with the following program code using the graft effect OpacityMask

  1. import QtQuick 2.12
  2. import QtQuick.Window 2.12
  3. import QtGraphicalEffects 1.13
  4.  
  5. Window {
  6. visible: true
  7. width: 640
  8. height: 480
  9. title: qsTr("Hello World")
  10.  
  11. Rectangle {
  12. id: rect
  13. x: 27
  14. y: 31
  15. width: 100
  16. height: 100
  17. color: "blue"
  18.  
  19. layer.enabled: true
  20. layer.effect: OpacityMask {
  21. maskSource: Item {
  22. width: rect.width
  23. height: rect.height
  24. Rectangle {
  25. anchors.centerIn: parent
  26. width: rect.adapt ? rect.width : Math.min(rect.width, rect.height)
  27. height: rect.adapt ? rect.height : width
  28. radius: 30
  29. }
  30. }
  31. }
  32.  
  33. Rectangle {
  34. x: -20
  35. y: -20
  36. width: 100
  37. height: 100
  38.  
  39. color: "green"
  40. }
  41. }
  42. }
  43.  

And the result will be as follows

Conclusion

In conclusion, I’ll say that clip is a very useful property, which for performance reasons was set to false by default. At the same time, this property performs only simple cropping in the form of a rectangle, and something more complex needs to be cropped using a mask.

Do you like it? Share on social networks!

f
  • Oct. 21, 2021, 3:24 p.m.

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

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

  1. layer.enabled: true
  2. layer.effect: OpacityMask {
  3. maskSource: Rectangle {
  4. width: rect.width
  5. height: rect.height
  6. radius: 30
  7. }
  8. }

Comments

Only authorized users can post comments.
Please, Log in or Sign up
  • Last comments
  • Evgenii Legotckoi
    April 16, 2025, 5:08 p.m.
    Благодарю за отзыв. И вам желаю всяческих успехов!
  • IscanderChe
    April 12, 2025, 5:12 p.m.
    Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
  • AK
    April 1, 2025, 11:41 a.m.
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    March 9, 2025, 9:02 p.m.
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    March 9, 2025, 4:14 p.m.
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…