Reputation: 927
I am using QML (Qt Quick) in order to set-up the GUI of an app and I am having weird behaviors.
Here is my initial piece of code:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle {
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar
{
id: progressBar1
value: 0.5
}
} }
... which gives layout:
Then I anchor the centers:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle
{
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar
{
id: progressBar1
value: 0.5
}
}
}
No problem here, I get:
Now things go wrong when I rotate the slider:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle
{
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar
{
id: progressBar1
rotation: 90
value: 0.5
}
}
}
And here I was expecting Qt to rotate the slider and use the rotated slider to compute the layout, but it is not what happens. Actually the layout seems to be computed with the slider unrotated then only the slider is rotated. This ends up with a layout which is no longer a column:
This looks a bit buggy, no? Or am I doing something wrong?
Now another problem occurs when I wrap the slider in an Item (I was actually playing with Items to see if I could find a workaround):
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Rectangle
{
id: rectangle1
color: palette.grey
ColumnLayout
{
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label
{
id: label1
text: qsTr("Target")
font.pointSize: 22
}
Item
{
ProgressBar
{
id: progressBar1
value: 0.5
}
}
}
}
And in this case what I get is a slider above the label (although it is defined after it in the code):
This also looks weird to me... Anybody has an idea of what I did wrong?
Please note that the screen shots are captured from Designer but running the program leads to the exact same problems.
Kind regards,
Antoine Rennuit.
Upvotes: 1
Views: 462
Reputation: 24386
Now things go wrong when I rotate the slider
Rotation doesn't affect the width
or height
properties. You can check this by adding the following lines to your ProgressBar
:
onWidthChanged: print("width", width)
onHeightChanged: print("height", height)
If ProgressBar
had an orientation
property, like it does in Qt Quick Controls 1, you could use that instead of rotation
. You can't simply flip the width
and height
when rotating the bar, either, because layouts use the implicitWidth
and implicitHeight
, not width
and height
:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
ApplicationWindow {
width: 400
height: 300
visible: true
ColumnLayout {
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label {
id: label1
text: qsTr("Target")
font.pointSize: 22
}
ProgressBar {
id: progressBar1
rotation: 90
width: implicitHeight
height: implicitWidth
value: 0.5
}
}
}
You could calculate the implicitWidth
and implicitHeight
yourself, but that's not nice.
Now another problem occurs when I wrap the slider in an Item
You're on the right track here. As mentioned in this answer, you need to give the Item
a size. You can do so like this:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
ApplicationWindow {
width: 400
height: 300
visible: true
ColumnLayout {
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label {
id: label1
text: qsTr("Target")
font.pointSize: 22
}
Item {
implicitWidth: progressBar1.implicitHeight
implicitHeight: progressBar1.implicitWidth
ProgressBar {
id: progressBar1
rotation: 90
value: 0.5
}
}
}
}
Notice that the progress bar still isn't in the correct position. That's because the default transform origin for items is in the centre. Setting it to the BottomLeft
works:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
ApplicationWindow {
width: 400
height: 300
visible: true
ColumnLayout {
id: columnLayout1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label {
id: label1
text: qsTr("Target")
font.pointSize: 22
}
Item {
implicitWidth: progressBar1.implicitHeight
implicitHeight: progressBar1.implicitWidth + progressBar1.implicitHeight
ProgressBar {
id: progressBar1
rotation: 90
transformOrigin: Item.BottomLeft
value: 0.5
}
}
}
}
Note that you also have to add the implicitHeight
of the bar to the implicitHeight
of the Item
, in order to account for the transform origin change we did.
I'd strongly recommend you create a suggestion for an orientation property on bugreports.qt.io. :)
Upvotes: 2