I am trying to show incremental changes on a progress bar by clicking a mouse area. The code below compiles and changes the value of the progress bar from 0 to 0.25 after clicking the mouse area. But the change is not permanent. I am trying to increase the current each click by 0.25. I know my code is only setting the value to positive .25 each click. I am just at a loss for how I might increment change in progress bar without global vars. I included the transition to ensure the state change was irreversible, the code still compiles and runs the same. There are two issues.
My change is not permanent in the visible progress bar
My increments do not increase the total value, they are singular value assignments
ProgressBar{
id: progressBar
height: 20
anchors.top: parent.top
anchors.topMargin: 100
anchors.horizontalCenter: parent.horizontalCenter
opacity: 1
value: 0
states: State{
name: "PressedAlso"
when: mouseArea.pressed == true
PropertyChanges{
target: progressBar
value: + 0.25
}
}
transitions: Transition {
from: ""; to: "PressedAlso"; reversible: false
}
}
Your state PressedAlso means: when the mouse button is pressed, the value is 0.25. Otherwise, the value is implicitly 0.
If you want to increment by 0.25 by pressing the mouse button, you can use onPressed property in your MouseArea:
MouseArea {
anchors.fill: parent
id: mouseArea
onPressed: progressBar.value += 1
}
Related
So in testing my program, I discovered the strangest thing.
So, I have a ListView element with a custom C++ model, and a fairly simple delegate. Each delegate is a MyButton class, which is simply a Text class(z:2), an Image class(z:1), and a MouseArea class. That Image class is the background, and contains a translucent image which becomes opaque when MouseArea is onPressed().
Now the strange part.
When the ListView has 4 elements, it operates normally -except- when the user selects entry #3, then entry #2 or #1.
When the selected entry goes from #3->#1, the text in entry #2 grays out as opposed to its normal white.
When the selected entry goes from #3->#2, the text in entry #2 completely disappears.
After hours of testing and banging head against desk, I've uncovered a bit more:
The opacity of MyButton or any of its children never changes.
The color of MyButton's text element never changes
The content of MyButton's test element never changes
After offsetting the text partially outside of MyButton, this abnormal behavior only affects the text remaining inside the bounds of MyButton's Image child.
The Z level of MyButton or any of its children never changes, though it appears as if MyButton's Image is being placed on top of its Text.
Another image is never placed on top of a MyButton element. If this was the case, when going from #3->#1 you would see the image of entry #2 become darker.
When the ListView is scrolled, everything returns to normal.
When ListView contains 4 elements, below are the abnormalities:
when #4->#1: #2 and #3 gray out
when #4->#2: #2 disappears
when #4->#3: #3 disappears
when #3->#2: #2 disappears
when #3->#1: #2 grays out
This is consistent to the image and text inside the MyButton class being re-ordered, placing the image a Z level above the text. However the z levels are forced in the MyButton definition, and an onZChanged signal is never created when these events happen.
Below is the relevant code:
//MyButton:
import QtQuick 2.0
Item {
id: button
property string source: ""
property string source_toggled: source
property string button_text_alias: ""
signal pressed
width: button_image.sourceSize.width
height: button_image.sourceSize.height
property bool toggled: false
Image{
id: button_image
z: 1
source: toggled ? parent.source_toggled : parent.source
}
MyText{
z: 2
text_alias: button_text_alias
anchors.centerIn: parent
}
MouseArea {
id: button_mouse
anchors.fill: parent
onPressed: button.pressed()
}
}
//ListView:
Component{
id: p_button
MyButton{
source: picture_path + "bar.png"
source_toggled: picture_path + "bar_selected.png"
toggled: model.isCurrent
onClicked: {
profile_model.setCurrent(model.index)
}
button_text_alias: model.display
}
}
ListView{
id: p_list
width: 623
height: count*74 -1
spacing: 1
interactive: false
model: p_model
delegate: p_button
}
I can't think of -anything- that could cause this behavior.. any ideas?
I was able to solve this error by breaking up my delegate into:
Component{
id: p_button
Item{
property bool toggled: model.isCurrent
width: button_image.sourceSize.width
height: button_image.sourceSize.height
Image{
id: button_image
visible: !toggled
source: picture_path + "bar.png"
}
Image{
visible: toggled
source: picture_path + "bar_selected.png"
}
MouseArea{
anchors.fill: parent
onClicked: p_model.setCurrent(model.index)
}
MyText{
text_alias: model.display
anchors.centerIn: parent
}
}
}
So instead of swapping the source of an object, there are two objects which become visible/invisible based on a boolean value. This prevented the issue, though I still don't know the cause.
Subj
I show my data on QML' Listview with delegated text, labels, and spinboxvalue elements of item. When user change the value of spinbox I need to know it and make some deals. But MouseArea works beyond of Spinbox, not on spinned buttons, onClicked event doesn't exists.
SpinBox {
id: goodsCountSpinBox
leftPadding: 1
rightPadding: 1
value: model.goodsCount
implicitWidth: 100
anchors.right: dataRow.right
MouseArea {
anchors.fill: parent
onClicked: {
listView.currentIndex = index; //Change the current selected item to the clicked item
console.log("SpinBox::MouseArea::onClicked")
}
}
By the way, and how to out current datetime in console log?
I found onValueChanged in examples but I don't find it in QML manuals.
SpinBox {
id: fontSizeSpinBox
activeFocusOnPress: false
implicitWidth: 50
value: 0
property bool valueGuard: true
onValueChanged: if (valueGuard) document.fontSize = value
}
I found to print current timestamp
Qt.formatTime(new Date()
If you want to just use the current value of the spinbox, just use its value property in a binding.
If you want to react to the value change, use the handler for the property's change signal, i.e. onValueChanged.
Hope this makes some sense as a question. In my app, I have a DragArea defined which I use to start dragging things over top of various Rectangles that each contain a DropArea. Everything is working fine in my code except for a cosmetic effect that I would like to change.
In QML, when you start dragging from a DragArea and eventually drop, the animation effect is such that the thing you're dragging animates (while fading out) back to the spot from which you started dragging. This happens even when you drop over a DropArea that successfully captures the drop.
What I would like to do is have the drop effect animate towards the DropArea that received the drop - so that it appears I am dragging-and-dropping things into the Rectangle. Is there any way to do this?
I'm guessing that this in some way involves the .source and .target properties of these areas, but no luck so far in having any effect on where the drop animation goes.
By default, QML will give you no cosmetic behavior for drag and drop whatsoever. The drag target will begin at the drag start location, and will end wherever it is dropped, regardless of whether the drag is accepted or not.
Thus I assume the behavior you describe is implemented in your user code, which you have not disclosed. Regardless, what you want to do is quite easy, it involves tracking the position the drag originates at and it ends at, so you can use the two coordinates to animate the position.
In the following example the red rectangle can be dragged, and if dropped outside of a drop area it will animate from its current to its initial position, whereas if dropped in the yellow rectangle, it will animate from its initial to its drop position.
Window {
width: 600
height: 600
visible: true
Rectangle {
width: 200
height: 200
color: "yellow"
DropArea {
anchors.fill: parent
onEntered: drag.source.accepted = true
onExited: drag.source.accepted = false
}
}
Rectangle {
id: rect
width: 50
height: 50
color: "red"
x: parent.width * 0.5
y: parent.height * 0.5
Drag.active: mouseArea.drag.active
property point begin
property point end
property bool accepted : false
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: parent
onPressed: rect.begin = Qt.point(rect.x, rect.y)
onReleased: {
rect.end = Qt.point(rect.x, rect.y)
aX.from = rect.accepted ? rect.begin.x : rect.end.x
aX.to = rect.accepted ? rect.end.x : rect.begin.x
aY.from = rect.accepted ? rect.begin.y : rect.end.y
aY.to = rect.accepted ? rect.end.y : rect.begin.y
anim.start()
}
ParallelAnimation {
id: anim
NumberAnimation { id: aX; target: rect; property: "x"; duration: 200 }
NumberAnimation { id: aY; target: rect; property: "y"; duration: 200 }
}
}
}
}
What I need to do: I need to create a chat window using a ListView in QML that stores the chat-messages. I set listView.positionViewAtEnd() in order to follow the last messages. I disable positionViewAtEnd when I scroll upwards such that I can read the past messages without jumping at the end every time I receive a new message.
The problem: After scrolling up, every time I receive a new message it jumps at the beginning of list. To solve that I manage to store the contentY of the list and reset it every time onCountChanged handler is called (see the code below):
ListView {
id: messagesList
model: contact? contact.messages: []
delegate: delegate
anchors.fill: parent
anchors.bottomMargin: 20
height: parent.height
anchors.margins: 10
property int currentContentY
onMovementEnded: {
currentContentY = contentY
}
onCountChanged: {
contentY = currentContentY
}
onContentYChanged: {
console.log(".....contentY: " + contentY)
}
}
The problem is that even though I set the last contentY I had, before the model was changed, the list still jumps a bit (several pixels, not at the end or beginning) and it doesn't jump always. And when I go to the top of the list and print the contentY I get negative values. Theoretically, contentY at the beginning of the list should be 0.
Can somebody tell me what is going wrong? Or maybe suggest another solution to create my message list?
Than you in advance! :)
One possible solution schould be insert ListView into Flickable and disable interactive flag for ListView
Flickable {
id: fparent
anchors.fill: parent
anchors.bottomMargin: 20
anchors.margins: 10
interactive: true
clip: true
flickableDirection: Flickable.VerticalFlick
contentHeight: messagesList.height
ListView {
id: messagesList
width: parent.width
height: childrenRect.height
clip: true
model: contact? contact.messages: []
delegate: delegate
interactive: false
onCountChanged: {
fparents.returnToBounds();
}
}
}
Why not use onCountChanged slot in order to set the ListView at the end ?
onCountChanged: {
messagesList.positionViewAtEnd()
}
Encountered the following problem with rendering in QML. I have implemented the 'minimize window' button:
Image {
source: "minimize.png"
scale: mouse.pressed ? 0.8 : 1.0
smooth: mouse.pressed
MouseArea {
id: mouse
anchors.fill: parent
anchors.margins: -5
onClicked: {
console.log("MinimizeButton clicked");
viewer.showMinimized();
}
}
}
where 'viewer' is the object inherited from QDeclarativeView which represents the main application window.
The button shrinks when user clicks the mouse onto it and window has been minimized. But button stays shrinked when window is restored.
Tried to add the timer which prints 'mouse.pressed' every 1 sec:
Timer {
repeat: true
interval: 1000
running: true
onTriggered: {
console.log("mouse.pressed =",mouse.pressed);
}
}
It always prints mouse not pressed. But button is scaled to 0.8, not 1.0.
"viewer.showMinimized()" appears to be guilty: button is rendered OK if it is commented out.
Any suggestions to solve the problem?