Reputation: 14938
I have to create some "tabs" in QML which should have rounded corners at the top and a border all over it :
I managed to create the rounded rectangle by using 2 rectangles :
(the tabs are part of a listview)
ListView {
id: listView
anchors.fill: parent
orientation: ListView.Horizontal
spacing: Math.floor(0.60 * parent.width / 100)
model: TabsModel{}
delegate: TabsDelegate {
height: parent.height
}
}
The delegate which is the actual tab :
Item {
id: root
width: 200
Rectangle {
id: topRect
anchors.fill: parent
radius: 5
color: backgroundColor
/*border.width: 1
border.color: borderColor*/
}
Rectangle {
id: bottomRect
anchors.bottom: parent.bottom
anchors.left: topRect.left
anchors.right: topRect.right
height: 1 / 2 * parent.height
color: backgroundColor
/*border.width: 1
border.color: borderColor*/
}
Text {
id: text
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: spaceBefore
text: label
color: textColor
}
}
With this code i have the following result :
Obviously if i add the borders , i end up with with a border in the middle of my tabs :
Any ideas how i can manage to get what i want in qml ?
Upvotes: 2
Views: 11480
Reputation: 24
I have recently needed a rounded rectangle with different radius in each corner and with border, so I implemented one. It depends on Qt 6 and uses shaders so it doesn't work with software rendering, still I hope it helps some people. The code is available at https://gitlab.com/Akeras/QmlRoundedRectangle
Upvotes: 1
Reputation: 49289
You could use a single rectangle if you can get away with tucking its bottom edge under something on the GUI. That's about all you can do out of the box as QML doesn't support custom corner angling. Granted, you can try covering that line up with yet another third rectangle, but that's clearly the wrong and messy approach you shouldn't be taking.
Otherwise you will have to do manual painting.
There is a number of options here.:
1 - use Canvas to draw from QML, and use that graphic with a BorderImage
, which will allow you to use the same, single time painted elements to drive an arbitrary size label. You can also use an image generated by a 3rd party program, but drawing it in QML is more flexible
2 - use QQuickPaintedItem
and draw the entire tab with C++ and QPainter
3 - implement a proper QQuickItem
that generates the needed geometry and renders the item efficiently with the QML scene graph in OpenGL.
Upvotes: 1
Reputation: 2051
You can simply add another Rectangle
(between bottomRect
and text
) to hide the middle border:
Rectangle {
anchors {
fill: bottomRect
leftMargin: bottomRect.border.width
bottomMargin: bottomRect.border.width
rightMargin: bottomRect.border.width
}
color: backgroundColor
}
Upvotes: 3