5

Can anyone help me how to round only one corner of a rectangle like shown in attached pic where red rectangle is my child rectangle.

Actually, I have a rectangle where all four corners rounded(radius 10). Now, i want to draw a new rectangle inside this and expecting only that particular corner should be rounded who touches the parent's round corner.

enter image description here

Rectangle
{
    id: parent
    radius: 10
    width: 168
    height: 168
    visible: true
    color: "black"

    Rectangle
    {
        id: child
        width: 100
        height: 40
        color: "red"
    }
}

I tried to do this with adding clip property in child but nothing happened.

dtech
  • 47,916
  • 17
  • 112
  • 190
RaviS Gupta
  • 95
  • 2
  • 11

5 Answers5

6

Here is a simple example. It is rounded in the upper left corner, but is easily adjusted to any other corner. Only one corner is supported in this solution, but it might be enough for you? More corners are little more complex, so ask again if you would need those aswell.

Rectangle {
    anchors.centerIn: parent
    id: root
    radius: 20
    width: 300
    height: 300

    Rectangle {
        id: clipper
        width: 100
        height: 100
        color: 'transparent'
        clip: true

        Rectangle {
            id: clipped
            width: parent.width + radius
            height: parent.height + radius
            radius: root.radius
            color: 'red'
        }
    }
}
3

Not with the stock Rectangle:

The same radius is used by all 4 corners; there is currently no way to specify different radii for different corners.

In C++ you could specify a horizontal and vertical radius, but still not per-corner radius. If you want such functionality, you will have to implement your own QQuickItem with the geometry node and all.

The result you want to achieve in the image could also be achieved with clipping, however unfortunately, in QML clipping only works for the item's rectangle, not the actual item geometry.

It will be easiest to achieve the desired effect using a BorderImage element. It enables to specify a different sub-image for every corner:

enter image description here

dtech
  • 47,916
  • 17
  • 112
  • 190
  • You could also use 4 Rectangles and put them together yourself. This would give you a little bit more versatility (changing the radius without the need to scale the image or use multiple versions of the picture). I have no Idea how bad the performance is. – derM - not here for BOT dreams Oct 10 '16 at 13:38
  • And that achieves what exactly? – dtech Oct 10 '16 at 13:39
  • See edit. Pressed return before adding the reason. Sry. – derM - not here for BOT dreams Oct 10 '16 at 13:42
  • @ddriver : Thanks. I was thinking as parent rectangle (in posted example) is already rounded and if he wouldn't allow to go any of his child out of his(parent) boundary. And if child rectangle crosses parent's border to be painted that time the area of child rectangle which is out of boundary should be either cropped or clipped. With this I can achieve what I want. Is any property of rectangle/Qml available to do this work, I mean that property does not allow to go his child to beyond boundary and get painted? I am new in Qml and don't know how valid my question is? – RaviS Gupta Oct 10 '16 at 16:30
  • @derM :Thanks Please comment on above query if you have anything related that. – RaviS Gupta Oct 10 '16 at 16:31
  • @RaviSGupta - as I said, QML works in such a way, that clipping will only clip to the item's rectangle, not the item's geometry. It is a rather annoying limitation. You could however try and use a rounded rectangle for an opacity mask as discussed in the answer here: http://stackoverflow.com/questions/39903639/how-to-apply-opacity-mask-to-a-qml-item/39907404#39907404 – dtech Oct 10 '16 at 16:39
1

It is possible using Shape item as below:

Shape {
    id: advancedShape
    width: 100; height: 40
    vendorExtensionsEnabled: true
    layer.enabled: true
    layer.samples: 4
    layer.smooth: true

    // set following properties to specify radius
    property real tlRadius: 0.0
    property real trRadius: 15.0
    property real brRadius: 0.0
    property real blRadius: 0.0

    ShapePath {
        strokeColor: "transparent"
        fillColor: "red"

        startX: 0; startY: advancedShape.tlRadius
        PathArc {
            x: advancedShape.tlRadius; y: 0
            radiusX: advancedShape.tlRadius; radiusY: advancedShape.tlRadius
            useLargeArc: false
        }
        PathLine {
            x: advancedShape.width - advancedShape.trRadius; y: 0
        }
        PathArc {
            x: advancedShape.width; y: advancedShape.trRadius
            radiusX: advancedShape.trRadius; radiusY: advancedShape.trRadius
            useLargeArc: false
        }
        PathLine {
            x: advancedShape.width; y: advancedShape.height - advancedShape.brRadius
        }
        PathArc {
            x: advancedShape.width - advancedShape.brRadius; y: advancedShape.height
            radiusX: advancedShape.brRadius; radiusY: advancedShape.brRadius
            useLargeArc: false
        }
        PathLine {
            x: advancedShape.blRadius; y: advancedShape.height
        }
        PathArc {
            x: 0; y: advancedShape.height - advancedShape.blRadius
            radiusX: advancedShape.blRadius; radiusY: advancedShape.blRadius
            useLargeArc: false
        }
        PathLine {
            x: 0; y: advancedShape.tlRadius
        }
    }
}

and result will be as this:
rectangle with round one corner

NOTE The builtin Rectangle has more performance than Shape, but I recommend Shape over masking because it works on any environment.

NOTE 2 I think the most true way in production is using BorderImage as @dtech suggested IF the radius is known and you don't need to change radius dynamically.

S.M.Mousavi
  • 5,013
  • 7
  • 44
  • 59
0

Created this from a bunch of rectangles. Two big rectangles and 4 smaller optionally rounded squares. This way you can also make different radii for each corner, not only turning them on and off. You just need to make sure that you don't want a too big rounding, because then the rounded rect would stick out.

Ambrus Tóth
  • 552
  • 6
  • 14
-1
Rectangle {
    id: clipper
    width: 10
    height: 10
    color: "transparent"
    clip: true

    Rectangle {
        id: clipped
        width: 30
        height: 30
        radius: 8
        color: "red"
    }
}
  • 3
    How does this solve the problem? Please add some context to the code and what its supposed to do. For more info on how to properly answer, see [answer] – Artog Aug 19 '19 at 12:33