How to draw a single sided line border in QML - qml

I've got 3 basic elements in a rectangle and I'd like to draw line separations between them.
I don't find an easy way to achieve that, as a border-left would do in CSS.
Text {
id : txtNote
text : (__notes.length>0)?__notes[0].extname.name:"--"
anchors.right: txtNoteAcc.left
leftPadding: 5
rightPadding: 0
}
Image {
id : txtNoteAcc
height : 20
width : 20
anchors.right: txtNoteHead.left
}
Image {
id : txtNoteHead
height : 20
width : 20
anchors.right: parent.right
}
Now laid out as:
And the goal is to have it a similar way (this example is a Java one):
I've found this approach, but I don't call it "simple" and it is 7 years old.
Rem: I'm working with QML 5.9 (so Shape is not available).

Related

Plasmoidviewer isn't centering widget upon launch

I'm learning how to make Plasmoids with QML, and I'm using Plasmoidviewer to view the package as I build it.
However, when I launch it, my widget is clipped into the lower right corner, like this:
If I resize the window a bit, then resize it back to the original size, the widget snaps into view:
The main.qml is just a simple Hello World:
Item {
//Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
Plasmoid.fullRepresentation: Rectangle {
color: "blue"
opacity: 0.3
Layout.minimumWidth: label.implicitWidth
Layout.minimumHeight: label.implicitHeight
Layout.preferredWidth: 640 * PlasmaCore.Units.devicePixelRatio
Layout.preferredHeight: 480 * PlasmaCore.Units.devicePixelRatio
PlasmaComponents.Label {
id: label
anchors.fill: parent
text: "Hello World!"
horizontalAlignment: Text.AlignHCenter
}
}
}
Any idea why this is happening, and how I can get the widget to be displayed in the center of plasmoidviewer? This is really annoying to develop with.

Align text to a circle / curved path

I'm making a vehicle's instrument cluster in QML and wanted to align the speed labels to the curve in such a way that they are all the same distance away from it. To do this, I used pathview to set up an arc, then used the text delegate to have the text appear in the right places. The reason it's not working exactly as intended is that some text is larger than other (for example '0' takes less space than '100') which causes some variability in distance between the text and the circle I'm trying to align it with. How can this be done better?
Here's the snippet of what I have got working so far:
Component {
id: spdLabel
Text {
font.weight: Font.Normal
font.pixelSize: 28
color: "white"
text: model.index
visible: model.index % spdMarkInterval == 0
}
}
PathView {
anchors.fill: parent
z: 0
model: topSpeed + 1
delegate: spdLabel
path: Path {
PathAngleArc {
centerX: (dialGauge.x + dialGauge.width)/2
centerY: (dialGauge.y + dialGauge.height)/2
radiusX: 140
radiusY: 140
sweepAngle: 270
startAngle: 135
}
}
}
Here's what the result looks like:
Since it is the center of text elements that's anchored a constant distance away from the arc, the distance between the text edge and arc varies.
Thanks for any help!

Design of 3 middle dots (...) in qml using Text and Rectangle

I want to design 3 dots in qml using Text and Rectangle as shown below;
... Hello World ...
But my requirement is 3 dots should lie at the middle of the rectangle and the text (Hello World) as shown in the image. How this can be achieved?
When I thought first time, 2 approaches came up in my mind:
1- Using the middle dot by the help of html code styles can achieve this. Here is the HTML codes which you can easiy use in qml.
Here is the example and output:
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle{
id:sample1
anchors.centerIn: parent
width: 200
height: 50
border.color: "black"
Text {
id: mytext
anchors.centerIn: parent
textFormat: Text.RichText
text: "·" + "·" + "·" + " Hello World " + "·" + "·" + "·"
}
}
}
Output:
2- You can put the "Hello world" text first then you can create another text for dots and put the dots in the mid coordinates beside the main text. This method is not a beautiful approach.
Note: When I dig into to other possible solutions, I couldn't see a proper solution to achieve this.

QML - How to correctly set an implicitWith to a GridLayout

I'm using Qml 5.12 and basically trying to set an implicitWidth to a GridLayout.
For that, I have a purple rectangle and set the rectangle's width to the GridLayout.
The red rectangle fit with the GridLayout so I can see the width of my GridLayout.
Here's my code:
Rectangle { anchors.fill: gl; color: "red"; opacity: 0.22 }
Rectangle { id: rect; width: 350; height: 30; color: "purple"; }
GridLayout
{
id: gl
y: 35
implicitWidth: rect.width
columns: 2
Label { text: "This is a test" }
SpinBox { Layout.alignment: Qt.AlignRight }
}
If I run the code, I expect to have my both rectangle with the same width.
But the actual result is that the red rectangle is smaller. So the implicitWidth was not considerate.
Can anybody tell my why ?
Thank's !
The GridLayout compute its own implicitWidth based on its children's implicitWidth. So the value you set gets overwritten by the computed one.
implicitWidth is the width an Item wants to have (and the one it would have if no width is explicitely set). Setting it based on something else than its children or some internal value makes little sense.
Here you want the GridLayout to be the exact size of your Rectangle so just set its width property.

QML - Control border width and color on any one side of Rectangle element

Currently i had a requirement of drawing a delegate rectangle with the help of ListView control. I was able to draw a series of rectangle either horizontal or vertical within the list view but the problem is with the border of the rectangle. The border width at the intersect point of the adjacent rectangle is of twice the width.
The delegate rectangle is nothing but a Qt Quick Rectangle element.
Is it possible to limit the border width on any one side of the rectangle alone?
Is it possible to change the color on any one side? (Something similar to QLineEdit - Where we can control the border width and color with respect to the sides)
Regards,
Santhosh.
You can make a custom border element like this :
CustomBorder.qml
import QtQuick 1.0
Rectangle
{
property bool commonBorder : true
property int lBorderwidth : 1
property int rBorderwidth : 1
property int tBorderwidth : 1
property int bBorderwidth : 1
property int commonBorderWidth : 1
z : -1
property string borderColor : "white"
color: borderColor
anchors
{
left: parent.left
right: parent.right
top: parent.top
bottom: parent.bottom
topMargin : commonBorder ? -commonBorderWidth : -tBorderwidth
bottomMargin : commonBorder ? -commonBorderWidth : -bBorderwidth
leftMargin : commonBorder ? -commonBorderWidth : -lBorderwidth
rightMargin : commonBorder ? -commonBorderWidth : -rBorderwidth
}
}
main.qml
import QtQuick 1.0
Rectangle
{
width: 500
height: 500
color: "grey"
Rectangle
{
anchors.centerIn: parent
width : 300
height: 300
color: "pink"
CustomBorder
{
commonBorderWidth: 3
borderColor: "red"
}
}
Rectangle
{
anchors.centerIn: parent
width : 200
height: 200
color: "green"
CustomBorder
{
commonBorder: false
lBorderwidth: 10
rBorderwidth: 0
tBorderwidth: 0
bBorderwidth: 0
borderColor: "red"
}
}
Rectangle
{
anchors.centerIn: parent
width : 100
height: 100
color: "yellow"
CustomBorder
{
commonBorder: false
lBorderwidth: 0
rBorderwidth: 0
tBorderwidth: 10
bBorderwidth: 10
borderColor: "blue"
}
}
}
In this example I have used the custom element to make different rectangles which have border on all, one or two sides.
The simplest solution for a ListView is to give your delegate a 1 pixel border and then use a spacing of -1 to get each cell to overlap the other by 1 pixel:
ListView {
spacing: -1
delegate: Rectangle {
height: 40
width: parent.width
border.width: 1
border.color: "black"
z: listView.currentIndex === model.index ? 2 : 1
...
}
...
}
It should work the same for other border widths.
EDIT: Added a nice enhancement from comment below that makes sure the selected item's border is always above all others so that if you change it to indicate selection it's not obscured by its neighbor delegates.
If you're trying to add borders between items in ListView, you should use the given property 'spacing' to establish a common border between each item. Then you could potentially add a background to the ListView to customize border colors.
Example:
ListView {
spacing: 1 // or whatever you want the border to be
}
...But if you really want a specific border you could always use Rectangles to make your own borders:
Item { // this is your 'rectangle'
Rectangle { // the main thing
id: rec
anchors.fill: parent
anchors.leftMargin: 2
anchors.rightMargin: 5
// etc
}
Rectangle { // a border example
anchors.right: rec.right
height: parent.height
width: 5
color: "red"
// etc
}
}
A bit late to answer but the accepted solution draws the border outside the geometry of the rectangle which can be problematic in some cases.
Another way to do this is to do something like:
// CustomBorderRect.qml
import QtQuick 2.12
Item
{
property alias color: innerRect.color
property alias borderColor : borderRect.color
property int borderWidth: 0
property int lBorderwidth : borderWidth
property int rBorderwidth : borderWidth
property int tBorderwidth : borderWidth
property int bBorderwidth : borderWidth
Rectangle
{
id: borderRect
anchors.fill: parent
Rectangle
{
id: innerRect
anchors {
fill: parent
leftMargin: lBorderwidth
rightMargin: rBorderwidth
topMargin: tBorderwidth
bottomMargin: bBorderwidth
}
}
}
}
This can then be used like this:
CustomBorderRect
{
width : 50
height: 30
color: "lightseagreen"
lBorderwidth: 0
rBorderwidth: 5
tBorderwidth: 5
bBorderwidth: 0
borderColor: "lightyellow"
}
This way the border is drawn with the given geometry.