How to give sleep in qml - qt

When I press the button now it instantly goes to the next page. Is it possible to give this loading.gif a sleep of 5 seconds?
I have tried to give it a duration: 5000 but then it gives an error
---- FULL CODE UPDATED ----
Login.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.15
Component
{
Rectangle
{
Rectangle
{
anchors.fill: parent
// Timer for Creating delay
Timer
{
id: timer
}
function delay(delayTime,cb)
{
timer.interval = delayTime;
timer.repeat = false;
timer.triggered.connect(cb);
timer.start();
}
ColumnLayout
{
// Some other items.
Button
{
onClicked:
{
backend.inloggen(email.text, wachtwoord.text, dropdown.currentText)
delay(5000, function()
{
loading_container.visible = true
})
stack.push(btnHomepage)
}
}
Rectangle
{
id: loading_container
visible: false
AnimatedImage
{
source: "./images/loading.gif"
}
}
}
}
}
}
Error: Login.qml:170: ReferenceError: delay is not defined
Sadly updating the the QtQuick nad QtQuick.controls update wasn't the solution

you can create delays by using Timer here is your code, I add one function that creates delay it gets duration like 5000 means 5 seconds, and one function that will be connected to Timer.
This function acts like a singleshot.
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
// Timer for Creating delay
Timer {
id: timer
}
function delay(delayTime,cb) {
timer.interval = delayTime;
timer.repeat = false;
timer.triggered.connect(cb);
timer.start();
}
Rectangle
{
id: loading_container
anchors.fill: parent
color: "#d71616"
anchors.rightMargin: 0
anchors.bottomMargin: 0
anchors.leftMargin: 0
anchors.topMargin: 60
visible: false
}
Button {
id: button
x: 0
y: 0
width: 151
height: 62
text: qsTr("Click me ")
onClicked:
{
delay(5000, function() {
loading_container.visible = true
})
}
}
}

As you update the question, Try this :
Component encapsulated QML types with well-defined interfaces.
the way that you use it is wrong.
The way that you use Function in your program is also wrong.
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
Item {
width: 640
height: 480
Timer
{
id: timer
}
function delay(delayTime,cb)
{
timer.interval = delayTime;
timer.repeat = false;
timer.triggered.connect(cb);
timer.start();
}
Rectangle
{
anchors.fill: parent
// Timer for Creating delay
// ColumnLayout
// {
// Some other items.
Button
{
onClicked:
{
// backend.inloggen(email.text, wachtwoord.text, dropdown.currentText)
delay(5000, function()
{
loading_container.visible = true
})
// stack.push(btnHomepage)
}
}
Rectangle
{
id: loading_container
visible: false
AnimatedImage
{
source: "what ever is your source path"
}
}
}
// }
}

In your code, the button doesn't have access to the Delay function, hence the reference error you get
Simply move the function to the button and the Timer in the root item

Related

QML Loading View during function runtime

I am attempting to create a qml button object that displays a screen for the duration of a function's runtime. I plan to use this loading screen when I need to parse through a larger dataset/run a slower function. Currently this is what I have come up with.
//LoadingButton.qml
import QtQuick 2.4
import QtQuick.Controls 1.2
Item
{
id: impl
function callbackFunction() { console.log("This is a dummy funciton and needs to be overwritten in the implementation") } //empty dummy function
property alias style: button.style
Button {
id: button
anchors.fill: parent
onClicked: {
loadingScreen.visible = true;
console.log("Loading should be visible")
impl.callbackFunction();
loadingScreen.visible = false;
console.log("Loading should be hidden")
}
}
Rectangle
{
width: 500
height: 500
x:0
y:0
z: 60
id: loadingScreen
color: "red"
visible: false
}
}
This example runs the callbackFunction once overwritten in the parent object correctly, but the visibility of the Rectangle does not change until the slower function is completed. Also the application freezes until it finishes.
Is there any way to force the Rectangle to show/hide mid-javascript function execution?
the best solution is of course to move your slow function to a background thread. That way the GUI stays responsive.
If you want to keep the callbackFunction in same thread as the GUI, you can use a Timer that will delay the start of the slow function until the loading screen is shown. Please note that the GUI will be blocked during the execution of the slow function.
import QtQuick 2.4
import QtQuick.Controls 1.2
Item
{
id: impl
function callbackFunction() {
console.log("This is a dummy funciton and needs to be overwritten in the implementation")
var cnt = 0
var largeNumber = 1
while (cnt < 99999999) {
largeNumber += largeNumber/3
cnt++
}
//put this at the end of your slow function
loadingScreen.visible = false;
console.log("Loading should be hidden")
}
property alias style: button.style
Button {
id: button
anchors.fill: parent
onClicked: {
loadingScreen.visible = true;
console.log("Loading should be visible")
timer.start()
}
}
Timer {
id: timer
interval: 500
repeat: false
onTriggered: impl.callbackFunction()
}
Rectangle
{
id: loadingScreen
width: 500
height: 500
x:0
y:0
z: 60
color: "red"
visible: false
BusyIndicator {
anchors.centerIn: parent
running: loadingScreen.visible
}
}
}

How to set objectName for PopupItem from QML?

QML Popup and derived controls are creating a PopupItem object which is a visual representation of it, but Popup itself is parented to the contentData of the application window. objectName specified for Popup is not applied to PopupItem. For example, the following application:
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Popup Test")
Button {
text: "Open"
onClicked: dummyPopup.open()
}
Popup {
id: dummyPopup
objectName: "dummyPopup"
x: 100
y: 100
width: 200
height: 300
modal: true
focus: true
}
}
creates PopupItem with empty objectName
Is there a way to set objectName for PopupItem from QML?
Set the objectName of its contentItem upon completion:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Popup Test")
Button {
text: "Open"
onClicked: dummyPopup.open()
}
Popup {
id: dummyPopup
objectName: "dummyPopup"
x: 100
y: 100
width: 200
height: 300
modal: true
focus: true
Component.onCompleted: {
contentItem.objectName = "foo"
print(contentItem)
}
}
}
By the way, if this is for auto tests, I have a hack in C++ that avoids the need to give an objectName to the contentItem:
QObject *TestHelper::findPopupFromTypeName(const QString &typeName) const
{
QObject *popup = nullptr;
foreach (QQuickItem *child, overlay->childItems()) {
if (QString::fromLatin1(child->metaObject()->className()) == "QQuickPopupItem") {
if (QString::fromLatin1(child->parent()->metaObject()->className()).contains(typeName)) {
popup = child->parent();
break;
}
}
}
return popup;
}
You can then use that function like this in your test:
const QObject *newProjectPopup = findPopupFromTypeName("NewProjectPopup");
QVERIFY(newProjectPopup);
QTRY_VERIFY(newProjectPopup->property("opened").toBool());

Why can't QML key events be intercepted?

I have the following code:
MyTest.qml
import QtQuick 2.0
FocusScope {
anchors.fill: parent
Keys.onReturnPressed: {
console.log("++++++++++")
}
}
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
MyTest {
focus: true
Keys.onReturnPressed: {
console.log("==========")
event.accepted = true
}
}
}
The output is:
++++++++++
==========
What is event.accepted = true invalid?
I want to intercept keystroke events in Window and process the event on ly in Window (only output "=========="). How to do that?
You can't disconnect a method when you use onReturnPressed: {} definition.
You have to use Connections for that.
A quick example:
import QtQuick 2.9
import QtQuick.Controls 1.4
Item {
id: myItem
anchors.fill: parent
property bool acceptEvents: true
signal returnPressed()
Keys.onReturnPressed: returnPressed()
Connections {
id: connection
target: myItem
enabled: acceptEvents
onReturnPressed: {
console.log("++++++++++")
}
}
}
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
VolumeSlider {
id: obj
anchors.fill: parent
focus: true
Keys.onReturnPressed: {
console.log("==========")
event.accepted = true
}
Component.onCompleted: {
obj.acceptEvents = false; // Remove connections
}
}
}

QML BusyIndicator while loading a heavy qml file

I've been trying to run a BusyIndicator (http://doc.qt.io/qt-5/qml-qtquick-controls-busyindicator.html) while I am loading a qml file (http://doc.qt.io/qt-5/qml-qtquick-loader.html), but the BusyIndicator doesn't appear.
What I am trying to do is:
1- The user emits a "handlerLoader(name)", where "name" is the url of the next qml page.
2- In "onHandlerLoader" I run the busyIndicator.
3- Then, I change the Loader source.
The problem is that no matter the time I spent between steps 2 and 3, the BusyIndicator does not appear.
Moreover, when I comment step 3, the busyIndicator appears correctly.
What I am doing wrong?
Thanks!!
This is the code:
Rectangle {
visible: true
width: 800
height: 480
signal handlerLoader (string name)
Loader {
id: pageLoader;
source: "init.qml";
}
BusyIndicator {
id: busyIndicator_inicio
width: 100
height: 100
anchors.centerIn: parent
running: false
}
Connections {
target: pageLoader.item
onHandlerLoader: {
busyIndicator_inicio.running = true
pageLoader.source = name;
}
}
}
The reason is, that your heavy-loading Loader is blocking the thread.
Set it to asynchronous mode, to allow the rest of the program to run.
Further, I'd recommend to prefer declarative bindings to imperative assignments in handlers. See my example:
main.qml:
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
Window {
width: 1000
height: 800
visible: true
Button {
text: 'load'
onClicked: {
loader.source = "TestObj.qml"
}
}
Loader {
anchors.fill: parent
id: loader
active: true
asynchronous: true
visible: status == Loader.Ready
}
BusyIndicator {
id: ind
anchors.fill: parent
running: loader.status == Loader.Loading
}
}
TestObj.qml:
import QtQuick 2.0
Item {
Grid {
anchors.fill: parent
columns: width
rows: height
Repeater {
model: 100
Rectangle {
width: { for (var i = 0; i < 10000; i++) console.log(i); return 1 }
height: 1
color: 'green'
}
}
}
}
Since the asynchronous Loader might display incomplete files for some time, I set it to be visible only when its status changes to ready.

Qt Quick borderless window not redrawn

I try to create a simple application where the user needs to enter a date. For this I want to connect a button with a calendar popup. This works fine as long as the popup is its own window and has a border. But the moment I make the window borderless it seems to be not drawn anymore. Actually if you move the underlaying window around you see that the area with the calendar widget stays undrawn.
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.1
ApplicationWindow {
width: 800
height: 600
property var pos : getOffset(dateField)
Button {
id: dateField
width: 100
height: 50
anchors.centerIn: parent
text: "show widget"
onClicked:{ toggleModal() }
}
function getOffset(item) {
var offset = {
"x": item.x,
"y": item.y + item.height
};
while(item.parent) {
item = item.parent;
offset.x += item.x;
offset.y += item.y;
}
console.debug("total", "x", offset.x, "y", offset.y)
return offset;
}
function toggleModal() {
if(modal.active) {
console.log("hide calendar")
loseFocus();
}
else {
console.log("show calendar")
modal.show()
modal.requestActivate()
}
}
function loseFocus(newDate) {
modal.close();
}
Window {
id: modal
flags: Qt.Window | Qt.FramelessWindowHint
//flags: Qt.Window
//modality: Qt.ApplicationModal
minimumHeight: calendar.height; minimumWidth: calendar.width
maximumHeight: calendar.height; maximumWidth: calendar.width
x: pos.x
y: pos.y
Calendar {
id: calendar
width: 200
height: 300
}
}
}

Resources