Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Rectangle radius only on top corners



  • Hi

    Sorry, newbie here.

    I have a simple Rectangle with a radius of 3.

    I've looked at the documentation but I did not find if is possible to have for example, only top corners rounded? Something like topLeftRadius: 3, or similar.

    If not possible directly, is there any other alternative? thanks

    PS: I'm using QtQuick



  • Hi @Pedro-Luz

    According to the documentation:

    there is currently no way to specify different radii for different corners.

    http://doc.qt.io/qt-5/qml-qtquick-rectangle.html#radius-prop


  • Moderators

    @Pedro-Luz

    I ran into that as well, heres my custom QML-item I made, where you can specifically say what corner shall be rounded:

    its a "Button" but you should be able to adapt the code to your needs.

    import QtQuick 2.11
    
    Item {
        id:root
        signal clicked()
    
        property color color: mArea.pressed ? "white" : "#32FFFFFF"
        onColorChanged: canVas.requestPaint()
    
        property int radius: root.height/3
        onRadiusChanged: canVas.requestPaint()
    
        property bool topLeftCorner: true
        property bool topRightCorner: false
        property bool bottomRightCorner: true
        property bool bottomLeftCorner: false
    
        onTopLeftCornerChanged: canVas.requestPaint()
        onTopRightCornerChanged: canVas.requestPaint()
        onBottomRightCornerChanged: canVas.requestPaint()
        onBottomLeftCornerChanged: canVas.requestPaint()
    
        property color borderColor: "black"
        onBorderColorChanged: canVas.requestPaint()
    
        property int borderWidth: 1
    
        property alias pressed: mArea.pressed
    
        Canvas {
            id:canVas
            anchors.fill: parent
    
            onPaint: {
                var context = getContext("2d");
                context.reset()
                context.beginPath();
    
                //Start position
                context.moveTo(0,height / 2)
    
                //topLeftCorner
                if(topLeftCorner){
                    context.lineTo(0,radius)
                    context.arcTo(0,0,radius, 0, radius);
                } else {
                    context.lineTo(0,0)
                }
    
                //topRightCorner
                if(topRightCorner){
                    context.lineTo(width - radius, 0)
                    context.arcTo(width, 0, width, radius, radius)
                } else {
                    context.lineTo(width, 0)
                }
    
                //bottomRightCorner
                if(bottomRightCorner) {
                    context.lineTo(width, height-radius)
                    context.arcTo(width, height, width - radius, height, radius)
                } else {
                    context.lineTo(width, height)
                }
    
                //bottomLeftCorner
                if(bottomLeftCorner) {
                    context.lineTo(radius, height)
                    context.arcTo(0, height, 0, height - radius, radius)
                } else {
                    context.lineTo(0, height)
                }
    
                //Close path
                context.lineTo(height / 2)
                context.closePath()
    
                //Draw border
                context.lineWidth = borderWidth
                context.strokeStyle = borderColor
                context.stroke()
    
                //Draw background
                context.fillStyle = color
                context.fill();
            }
        }
    
        MouseArea{
            id: mArea
            anchors.fill:parent
            onClicked: root.clicked()
        }
    
    }
    


  • Thats bad

    Thanks anyway, I'll see if I can experiment with http://doc.qt.io/qt-5/qml-qtgraphicaleffects-opacitymask.html



  • You can, just use Shape instead: https://doc.qt.io/qt-5/qml-qtquick-shapes-shape.html



  • There's the simplistic strategy of covering the corners that should remain square. Eg radiused on the top left and right, and bottom left:

    Rectangle {
        radius: 3
        Rectangle {
            width: parent.radius
            height: parent.radius
            anchors {
                bottom: parent.bottom
                right: parent.right
            }
            color: parent.color
        }
    }
    


  • The OpacityMask is quite a bit more powerful:

    // masking objects to unique shapes
        Rectangle {
            id: mask
    
            width: output.width
            height: output.height
    
            color: "transparent"
    
            Rectangle {
                id: corner_mask
                property real size: parent.width * 0.1
                width: size*2
                height: size*2
                radius: size*2
    
                color: "red"
    
                visible: false
            }
            Rectangle {
                id: corner_rect
                width: corner_mask.width
                height: corner_mask.height
    
                visible: false
            }
            ShaderEffectSource {
                id: shader_effect_mask
                sourceItem: corner_mask
                sourceRect: Qt.rect(0,0,corner_mask.width/2,corner_mask.height/2)
            }
    
            OpacityMask {
                anchors.left: parent.left
                anchors.top: parent.top
                width: corner_mask.width/2
                height: corner_mask.height/2
    
                maskSource: shader_effect_mask
                source: corner_rect
    
                invert: true
            }
            OpacityMask {
                anchors.right: parent.right
                anchors.top: parent.top
                width: corner_mask.width/2
                height: corner_mask.height/2
    
                rotation: 90
    
                maskSource: shader_effect_mask
                source: corner_rect
    
                invert: true
            }
    
            Text {
                width: output.width
                text: "The OP is from 2018"
                font.pixelSize: 100
                font.bold: true
                wrapMode: Text.WordWrap
                horizontalAlignment: Text.AlignHCenter
    
                anchors.centerIn: parent
            }
    
            visible: false
        }
        // the maskee
        Rectangle {
            id: output
    
            width: 512
            height: 256
    
            color: "steelblue"
    
            visible: false
        }
        // just do it!
        OpacityMask {
            source: output
            maskSource: mask
    
            width: output.width
            height: output.height
    
            invert: true
        }
    

Log in to reply