QML property is null - qml

I'm trying to define a property with a default value in a reuseable QML component. Here's my code thus far:
property alias value: progressBar.value
property bool error: false
property ProgressBarStyle errorStyle: ProgressBarStyle {
background: Rectangle {
radius: 2
color: "lightgray"
border.color: "gray"
border.width: 1
implicitWidth: 200
implicitHeight: 24
}
progress: Rectangle {
color: "orangered"
border.color: "red"
}
}
Layout.fillWidth: true
ProgressBar {
id: progressBar
Layout.fillWidth: true
minimumValue: 0.0
maximumValue: 100.0
style: errorStyle
}
So the idea is errorStyle is constructed and set as the style of progressBar. I know that errorStyle works, because if I set it directly on progressBar it works. From what I can tell, the problem is errorStyle is null when I run my program.
UPDATE:
Maybe a better way of stating this question is: "How do I get around the 'PropertyChanges does not support creating state-specific objects.' error message that I get if I create the style directly in the PropertyChanges array?
UPDATE 2:
I"ve basically given up on this approach and decided to try and using styling instead. This has lead to another question: Cannot create certain QML types in a singleton

You can try declaring it with an id, and use the id. So dont declary it as a property but just like a component. Like this:
ProgressBarStyle {
id: errorStyle
background: Rectangle {
radius: 2
color: "lightgray"
border.color: "gray"
border.width: 1
implicitWidth: 200
implicitHeight: 24
}
progress: Rectangle {
color: "orangered"
border.color: "red"
}
}
ProgressBar {
id: progressBar
Layout.fillWidth: true
minimumValue: 0.0
maximumValue: 100.0
style: errorStyle
}
But the approach i would take would be the make a property color and bordercolor and change the rectangle color of the style instead of changing the style completely.
Like this:
property Color barColor
property Color barBorderColor
property Color progressColor
property Color progressBorderColor
ProgressBar {
id: progressBar
Layout.fillWidth: true
minimumValue: 0.0
maximumValue: 100.0
style: ProgressBarStyle {
background: Rectangle {
radius: 2
color: barColor
border.color: barBorderColor
border.width: 1
implicitWidth: 200
implicitHeight: 24
}
progress: Rectangle {
color: progressColor
border.color: progressBorderColor
}
}
}

Related

QML Change ScrollBar Handle Color

I want to change the scrollbar handle color, and follow the Qt doc
https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-scrollbar
here is my code.
ScrollView {
id: view
anchors.top: parent.top
anchors.left: parent.left
contentHeight: 300
contentWidth: view.width
width: 200
height: 200
focus: true
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
Label {
text: "ABC"
font.pixelSize: 224
}
background: Rectangle{
color:"pink"
}
ScrollBar.vertical: ScrollBar {
parent: view
id: control
active: true
contentItem: Rectangle {
implicitWidth: 6
implicitHeight: 100
radius: width / 2
color: control.pressed ? "#81e889" : "#c2f4c6"
}
}
}
enter image description here
this result the handle will fill with scrollbar.
how to changed handle color and do not fill scrollbar?
here is update.
Try to setting implicitHeight to view.contentHeight
ScrollBar.vertical: ScrollBar {
parent: view
id: control
active: true
contentItem: Rectangle {
implicitWidth: 6
implicitHeight: view.contentHeight
radius: width / 2
color: control.pressed ? "#81e889" : "#c2f4c6"
}
}
here is result
It is have same problem,it's change the whole ScrollBar, not handle.

Error when customizing Controls 2 SpinBox

When customizing a QtQuickControls2 SpinBox, I get this error in the console when closing my application :
"There are still \"2\" items in the process of being created at engine destruction."
The number varies depending on how many Spinboxes are in the windows, it goes up for every indicator that was customized (two times per customized SpinBox : one for the up indicator, one for the down indicator). I tried commenting out each part of my custom code, as well as using the example code provided here, so I am positive that this is where the error comes from.
Does anyone know how to get rid of this error ?
Main window code :
import QtQuick 2.7
import QtQuick.Controls 2.3
ApplicationWindow{
width: 1600
height: 900
visible: true
SpinBox_custom{
}
}
Custom SpinBox_custom code :
import QtQuick 2.11
import QtQuick.Controls 2.4
SpinBox {
id: control
value: 50
editable: true
contentItem: TextInput {
anchors.fill: parent
anchors.rightMargin : up.indicator.width
anchors.leftMargin : down.indicator.width
z: 2
text: control.textFromValue(control.value, control.locale)
font.pointSize: Style.textPointSize-2
color: '#7e8d9e'
selectionColor: '#7e8d9e'
selectedTextColor: "white"
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
readOnly: !control.editable
validator: control.validator
inputMethodHints: Qt.ImhFormattedNumbersOnly
}
up.indicator: Rectangle {
x: control.mirrored ? 0 : parent.width - width
height: parent.height
implicitWidth: 20
implicitHeight: 30
color: control.up.pressed ? '#dee2e6' : '#bec6ce'
border.color: enabled ? '#bec6ce' : '#dee2e6'
Text {
text: "+"
font.pixelSize: control.font.pixelSize * 2
color: '#428AC9'
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
down.indicator: Rectangle {
x: control.mirrored ? parent.width - width : 0
height: parent.height
implicitWidth: 20
implicitHeight: 30
color: control.down.pressed ? '#dee2e6' : '#bec6ce'
border.color: enabled ? '#bec6ce' : '#dee2e6'
Text {
text: "-"
font.pixelSize: control.font.pixelSize * 2
color: '#428AC9'
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
background: Rectangle {
implicitWidth: 90
}
}
I've just faced the same problem and after some experiments seemed to find that it's somewhat connected to assigning literal values to the value property of SpinBox.
Something similar is also discussed in this report, and these are other things asking for trouble when used in SpinBox mentioned there:
references between internal elements of SpinBox (contentItem, background, [up,down].indicator's)
references to parent in internal elements
assigning id to internal elements
After getting rid of all of that and also changing value: 0 to value: from it automagically stopped warning me with the message in the original post.
Just as a reference, here's the snippet which works for me without the warning:
SpinBox
{
id: control
value: from
from: 0
to: 600
editable: true
enabled: true
leftPadding: topPadding
rightPadding: height
contentItem: Item
{
anchors.left: control.left
anchors.top: control.top
anchors.bottom: control.bottom
implicitWidth: input.implicitWidth
implicitHeight: input.implicitHeight
width: control.width - control.height
height: control.height
TextInput
{
id: input
anchors.fill: parent
text: control.textFromValue(control.value, control.locale)
color: "black"
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
readOnly: !control.editable
validator: control.validator
inputMethodHints: Qt.ImhFormattedNumbersOnly
}
}
up.indicator: Rectangle
{
anchors.top: control.top
anchors.right: control.right
anchors.topMargin: 1
anchors.rightMargin: 1
height: control.height / 2
width: control.height
color: "gold"
}
down.indicator: Rectangle
{
anchors.bottom: control.bottom
anchors.right: control.right
anchors.bottomMargin: 1
anchors.rightMargin: 1
height: control.height / 2
width: control.height
color: "orange"
}
background: Rectangle
{
implicitWidth: 100
border.color: "red"
border.width: 1
radius: 2
}
}

QML Slider : handle and mouse cursor

I created a slider in an item and customized it like in the following code :
Item {
id: item1
x: 0
y: 0
width: 200
height: parent.height
Rectangle {
id: background
anchors.fill: parent;
color:Qt.rgba(0.9,0.9,0.9,1);
}
Slider {
anchors.centerIn: parent
orientation: Qt.Vertical
height: parent.height
style: SliderStyle {
groove: Rectangle {
implicitWidth: 200
implicitHeight: 8
color: "gray"
radius: 8
}
handle: Rectangle {
anchors.centerIn: parent
color: control.pressed ? "white" : "lightgray"
border.color: "gray"
border.width: 2
width: 20
height: 20
radius: 6
}
}
}
}
The problem appears when I change the size of the handle to have it wider than high, so I change in the handle :
width: 20
height: 80 //the height is changed instead of width but I think
//it's because it is a vertical slider
And then, when I move the handle, it doesn't stay under the mouse cursor but there is an offset between the two.
How to fix that?
The slider is internally rotated 90 degrees when the orientation is vertical, so you'll need to set the width instead of the height. In other words, always style the handle assuming that the slider is horizontal, and the rest will just work...
... except for the mouse offset bug that you just ran into. It appears that your use case isn't auto-tested. Please submit a bug report at bugreports.qt.io.

Image size different after second click on it

I have following minimal working example, taken from my current project:
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
Window {
visible: true
width: Screen.width/2
height: Screen.height/2
property real ueMinOpacity: 0.00
property real ueMaxOpacity: 1.00
Rectangle {
anchors.fill: parent
anchors.margins: 8
border.color: "#4682b4"
radius: 16
clip: true
gradient: Gradient {
GradientStop {
position: 0
color: "#ffffff"
} // GradientStop
GradientStop {
position: 1
color: "#303030"
} // GradientStop
} // Gradient
Rectangle {
anchors.fill: parent
antialiasing: true
border.color: "#4682b4"
border.width: 1
radius: 16
clip: true
gradient: Gradient {
GradientStop {
position: 0
color: "#ffffff"
} // GradientStop
GradientStop {
position: 1
color: "#000000"
} // GradientStop
} // Gradient
RowLayout {
spacing: 8
anchors.fill: parent
TextField {
id: ueProductSearchTextField
antialiasing: true
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignLeft|Qt.AlignVCenter
Layout.margins: 8
placeholderText: qsTr("Enter product info")
} // TextField
Rectangle {
id: ueImageWrapper
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight|Qt.AlignVCenter
Layout.margins: 8
antialiasing: true
border.color: "#4682b4"
border.width: 1
radius: 16
clip: true
visible: ueProductSearchTextField.length > 0
gradient: Gradient {
GradientStop {
position: 0
color: "#636363"
} // GradientStop
GradientStop {
position: 1
color: "#303030"
} // GradientStop
} // Gradient
Image {
anchors.fill: parent
source: "http://www.clipartbest.com/cliparts/9iR/gEX/9iRgEXXxT.png"
antialiasing: true
clip: true
smooth: true
fillMode: Image.PreserveAspectFit
horizontalAlignment: Image.AlignHCenter
verticalAlignment: Image.AlignVCenter
sourceSize.width: 96
sourceSize.height: 96
} // Image
MouseArea {
anchors.fill: parent
enabled: ueImageWrapper.visible
onClicked: {
ueProductSearchTextField.text="";
} // onClicked
} // MouseArea
onWidthChanged: {
print("ueImageWrapper.width:"+ueImageWrapper.width);
} // onWidthChanged
onHeightChanged: {
print("ueImageWrapper.height:"+ueImageWrapper.height);
} // onHeightChanged
} // Rectangle
} // RowLayout
} // Rectangle
} // Rectangle
} // Window
Now, the purpose of this Item/Rectangle is to filter database records according to TextField's entered value, which works perfectly. However, once TextField's text is not empty anymore (when user enters some string), on the right side of Layout Image for clearing text is shown via OpacityAnimator. Once the app is launched, I get following screenshot - clear text icon is hidden since there is not text in TextField:
Then, I enter some text into TextField and clear text icon pops up:
Then, for instance, I clear text by clicking on clear text icon and it (icon) is hidden again, which is ok:
And finally, I reenter text into TextField, clear text icon is visible again, but it has different size:
Why? I did not change the code. It must be some problem with Layouts, but I simply do not see it! Here is also a debug output from onWidthChanged and onHeightChanged handlers:
qml: ueImageWrapper.width:37.56521739130435
qml: ueImageWrapper.height:480
qml: ueImageWrapper.width:132.92307692307693
qml: ueImageWrapper.width:133.83783783783784
BaCaRoZzo's suggestion works, but I'm also a bit unsure about why it behaves the way it does. If you take a simpler example:
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0
Window {
visible: true
width: 800
height: 800
Shortcut {
sequence: "Ctrl+Q"
onActivated: Qt.quit()
}
Item {
id: boundary
width: 400
height: 400
anchors.centerIn: parent
RowLayout {
anchors.fill: parent
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: "steelblue"
}
Rectangle {
id: rect
Layout.fillWidth: true
Layout.fillHeight: true
color: "salmon"
visible: false
}
}
}
Rectangle {
anchors.fill: boundary
color: "transparent"
border.color: "black"
}
Button {
text: "Toggle visibility"
onClicked: rect.visible = !rect.visible
}
}
The second rectangle starts off being invisible, and is then shown/hidden by clicking the button. However, when it starts off as invisible, it never gets a size once shown. On the other hand, if it starts off visible, then it gets half the width of the layout.
If you read the documentation carefully, it doesn't say that it's necessary to set a preferredWidth/preferredHeight if you just want to make an item fill the available space. For that reason, it seems like a bug in how layouts handle initial visibility of their items. I'd suggest filing a bug report.

Animating using NumberAnimation and Behavior

I'm trying to understand the functionality of Behavior by animating a small Rectangle when it's property changes.
Consider the following example:
import QtQuick 2.4
import QtQuick.Controls 1.2
Item {
width: 600
height: 80
Rectangle {
id: rect
color: "red"
width: 20
height: 20
property int xval: 0
Behavior on xval {
NumberAnimation {
target: rect
property: "x"
to: rect.xval
duration: 2000
easing.type: Easing.InOutQuad
}
}
}
Button {
anchors.bottom: parent.bottom
onClicked: { rect.xval=250 }
}
}
Here I'm trying to animate the x property of the Item rect on Button Click. But it doesnot animate. Now if you replace
to: rect.xval
with
to: 400
The Rectangle animates as expected on Button Click. All I want to do is to animate the Rectangle using the value set by the user. Am I missing something ?
You don't need a extra property to animate a property.
Behavior on foo will animate foo whenever it changes its value and make it the implicit property of inner Animations.
Your code can simply be
Item {
width: 600
height: 80
Rectangle {
id: rect
color: "red"
width: 20
height: 20
Behavior on x {
NumberAnimation {
duration: 2000
easing.type: Easing.InOutQuad
}
}
}
Button {
anchors.bottom: parent.bottom
onClicked: { rect.x=250 }
}
}