QML Image source is not updated while mouse is pressed - qt

I have ImageButton.qml which should change image when user holds the button.
import QtQuick 2.0
Image {
id: svg
property string idleImage
property string hoverImage
signal clicked
state: "idle"
source: state === "idle" ? idleImage : hoverImage
onSourceChanged: {
console.log("source = " + source)
}
MouseArea {
id: mouseArea
anchors.fill: parent
acceptedButtons: Qt.LeftButton
onPressedChanged: {
svg.state = pressed ? "hover" : "idle"
}
onClicked: svg.clicked()
}
}
But the image is not changed immediately. It's changed only when I hold the button for several seconds. When I press and release mouse button immediately I never see the hover image. onSourceChanged is executed immediately and outputs to console the right image source. This strange bug happens only when I use QQuickWidget. When I don't use widgets, but qml only everything works as expected.

I found the issue. I am using QOpenGLWidget in the MainWindow. And I called update method in paintGL.
void Workspace::paintGL() {
QOpenGLWidget::paintGL();
workspaceDrawer.draw();
update();
}
I replaced update call with a timer, running every 1000 / 60 milliseconds.
And the issue was gone. It's strange that it was reproduced only when a mouse button was pressed, otherwise everything was updated correctly.

Related

QML BusyIndicator how to overlay the current window, like ProgressDialog in Android

Iam using QML Busyindicator when a user login or loading a data in a page or something like this, I want to be able to make the busyindicator overlay over the current window and make the window not editable, something similar to the messagebox when it shows up and disables all the Window, so I cant interact with the widgets on this window until the loading finish, something like the ProgressDialog in Android.
this is my code and what I try to do, also I tried to use MessageDialog and use this indicator inside it and remove all buttons, but it does not work.
Popup {
id: waitpop
width: 100
height: 100
BusyIndicator {
id: login_progress
running: true
anchors.fill: parent
}
anchors.centerIn: Overlay.overlay
closePolicy: Popup.NoAutoClose
}
this code shows the busy indicator but the user still can interact with the button and text field and everything, so any ideas?
The modal property prevents you from being able to click outside the popup.
Popup {
anchors.centerIn: Overlay.overlay
closePolicy: Popup.NoAutoClose
modal: true
BusyIndicator {
running: true
}
}

Stackview Push and Pop destroys and creates a new page

I have many pages and when a button is clicked I make transitions between these pages with a StackView, push and pop. And in these pages when corresponding buttons are clicked I make these buttons red. However, when I pop and re-opened the same page with a push, button is no longer red. So that makes me think that pop and push destroys and creates a new page which is the opposite what is written in docs:
This means that any item pushed onto a StackView will never be
destroyed by the StackView; only items that StackView creates from
Components or URLs are destroyed by the StackView.
Here is the code for stackview:
Window{
id:main
property bool isAbsOffRoad: false
StackView{
id:contentFrame
initialItem:Qt.resolvedUrl("qrc:/MainPage.qml")
Connections{
target:contentFrame.currentItem
onBackButtonPressed:{
contentFrame.pop() }
}}
And then here is how I push:
Item {
id:backgroundItem
LeftButtons{
id:buttonSettings
MultiPointTouchArea{
onPressed{
contentFrame.push("qrc:/SettingsPage.qml")}
}}
I cannot see a reason why the page doesn't preserves it's state when popped and pushed back. What might be the reason?
Another question is: I get a
QML Connections: Cannot assign to non-existent property
"onBackButtonPressed".
However, back buttons work. Why I get that error?
The documentation you quote gives you the answer.
This means that any item pushed onto a StackView will never be destroyed by the StackView; only items that StackView creates from Components ->or URLs<- are destroyed by the StackView.
If a StackView creates an item from a URL, it will have ownership of it, and therefore feel free to destroy it.
Your code shows this:
initialItem:Qt.resolvedUrl("qrc:/MainPage.qml")
So you're giving the StackView a URL to your QML. If you don't want it to do that, try doing something like this instead:
initialItem: MainPage {}
That way, the StackView will be given a fully constructed item, and it won't try to destroy it.
For your second question, I'm guessing that your MainPage.qml does not define that signal. You could create that signal in MainPage just to remove the warning, or you can try adding the ignoreUnknownSignals property to your Connections object.
UPDATE:
You can still use push and pop. You just have to provide a created instance of your item, not just the item type. You could try something like this, for example:
component SomePage: Rectangle {
signal clicked()
MouseArea {
anchors.fill: parent
onClicked: parent.clicked()
}
Component.onCompleted: {
console.log("Created: " + color);
}
Component.onDestruction: {
console.log("Destroyed: " + color);
}
}
SomePage {
id: bluePage
color: "blue"
visible: false
onClicked: contentFrame.push(redPage)
}
SomePage {
id: redPage
color: "red"
visible: false
onClicked: contentFrame.pop();
}
StackView {
id: contentFrame
anchors.fill: parent
initialItem: bluePage
}

Catching mouse events from QML

I want to create a QML item which disappears when the mouse moves outside of it. Here is my code:
Item {
id: disappearing_element
ListView { ... }
MouseArea {
id: collapser
anchors.fill: parent
propagateComposedEvents: true
hoverEnabled: true
onExited: {
disappearing_element.visible = false
}
}
}
It works well, but MouseArea propagates events like onClicked() onDoubleClicked() only (as said in Qt docs).
Is there a way to notify disappearing_element's childrens about mouse enter and mouse exit events (without using a Popup element)?
I think this is one of the common needs when developing QtQuick apps. One solution we currently use quite often is to add MouseArea in each of the children that need check mouse containment, and emit signals (and catch these signals in your main item) when the mouse enters or exits.
Things go a bit complicated when the children items also need such mechanism to manage their children. However, for common usage, this approach is enough for us right now.

Ubuntu SDK: How do I implement a “onClick” for an image in QML?

I have a background image for my page, and I want to implement a sort of page refresh when the background is clicked. However, I didn't find any actions for the image element in QT quick.
What's the right way to implement this?
You need to use MouseArea to handle click events.
Image {
source: "myimage.png"
MouseArea {
anchors.fill: parent
onClicked: {
// do what you want here
}
}
}

QML signal executed twice

I'm new in QML and QML signals and I'm having this silly problem that I'm not being able to resolve by myself. I'm triggering an onTouch signal and is executing twice, generating a double response that crashes my app.
Here's my QML code:
//LabelKey.qml
import bb.cascades 1.0
Container {
property string labelText: "#"
property real width: 153.3
property real height: 102.5
property int labelPosX: 60
property int labelPosY: 25
property int labelTextFontWidth: 45
property string imgSrc: "asset:///images/keyboard_button.png"
layout: AbsoluteLayout {
}
preferredWidth: width
preferredHeight: height
objectName: "contTecla"
id: contTecla
ImageView {
objectName: "imgTecla"
id: imgTecla1
imageSource: imgSrc
preferredWidth: width
preferredHeight: height
onTouch: {
textFieldKey.text = textFieldKey.text + labelTecla.text;
}
}
Label {
objectName: "labelTecla"
id: labelTecla
text: labelText
textStyle {
color: Color.DarkYellow
size: labelTextFontWidth
}
layoutProperties: AbsoluteLayoutProperties {
positionX: labelPosX
positionY: labelPosY
}
}
}
I have this TextField whose id is textFieldKey in another QML where I'm including the one I post above. The main idea is simple, is a keyboard where each key is a component of the code above and it has to print the value of the key pressed in this TextField.
The problem is, as I said, the signals is being called twice, filling the TextField with two chars of the value each time.
Please help me I don't know if maybe I'm missing something in the proper way of using signals or something like that.
Thanks!
I figure it out. The touch signals has 4 differents states:
Down: Occurs when the user touches the screen.
Move: Occurs when the user moves a finger on the screen.
Up: Occurs when the user releases a finger.
Cancel: Occurs when an interaction is canceled.
Each one identify with a number from 0 to 3.
And when a touch signal is triggered two states are involved, Down and Up. You just need to make sure with wich one you want to work with and catch it inside the onTouch signal:
if (event.touchType == numberOfTheTouchState){
}
You want to use
ImageView
{
objectName: "imgTecla"
id: imgTecla1
imageSource: imgSrc
preferredWidth: width
preferredHeight: height
onTouch:
{
if(event.isDown())
{
textFieldKey.text = textFieldKey.text + labelTecla.text;
}
}
}
As was noted, without this you get both the up and down events

Resources