1

I'm looking for the way to use QThread in QML. I want to pass parameters to the QThread function and return a bool value from it.

Another thing I want from the QML side is to not block the app when it's executing a script that will happen before calling/executing the QThread.

Below is an example code:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "testasync.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    qmlRegisterType<testAsync>("testAsync",1,0,"thread");//not working on main.qml
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
//import testAsync 1.0

ApplicationWindow {
    id: window
    title: "Stack"
    visible: true
    width: 1400

    Page {
        id: page
        anchors.fill: parent
        property int responsiveWidth: 1000
        property int maximumWidth: 900
        ScrollView {
            id:configScroll
            anchors.fill: parent
            GridLayout {
                columns: 2
                width: page.width > page.responsiveWidth ? page.maximumWidth : page.width
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.leftMargin: page.width > page.responsiveWidth ? (page.width - childrenRect.width)/2 : 10
                anchors.rightMargin: page.width > page.responsiveWidth ? 0 : 10
                //this function needs to be processed and will return the values we need for the testasync. this can't block UI thread too
                function teste() {
                            for(var i=0; i<10000000; i++)
                            {
                                console.log(i)
                            }
                  return "teste"
                 }
                    Button {
                        property bool test: true
                        text: "async"
                        onClicked: {
                            var val = parent.teste()
//                            if(test)
//                                val=thread.start()
//                            else
//                                val=thread.quit()
                            console.log(val)
                            test=!test
                        }
                    }
            }
        }
    }
}

testasync.h

#ifndef TESTASYNC_H
#define TESTASYNC_H
#include <QThread>
#include <QObject>

class testAsync : public QThread
{
    Q_OBJECT
public:
    testAsync();
    void run();
private:
    QString name;
};
#endif // TESTASYNC_H

testasync.cpp

#include "testAsync.h"
#include <QDebug>
#include <QtCore>
testAsync::testAsync(){}

void testAsync::run() {
    for(int i = 0; i <= 100; i++)
    {
        qDebug() << this->name << " " << i;
    }
    //return true
}

How can these be done?

3
  • 1
    I'm not sure, but shouldn't the first letter of this type be a capital letter? Looks like this post has the same issue, check it. Commented May 14, 2019 at 11:00
  • @folibis i based myself on that post. What is the letter youre refering? Commented May 14, 2019 at 11:57
  • The item type should be Thread, not thread. In QML item type name could not be started with a small character. That besided the fact that Thread could be a reserved word. Commented May 14, 2019 at 12:14

2 Answers 2

2

Register the type correctly:

qmlRegisterType<testAsync>("TestAsync", 1, 0, "TestAsync");

Make a instance of your type in the qml file and call the methods of it.

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import TestAsync 1.0

ApplicationWindow {
    id: window
    title: "Stack"
    visible: true
    width: 1400

    TestAsync {
        id: threadAsync
    }

    Page {
        ....
                    Button {
                        property bool test : true
                        text: "async"
                        onClicked: {
                            if(test) {
                                val=threadAsync.start()
                            } else {
                                val=threadAsync.quit()
                            }
                            console.log(val)
                            test=!test
                        }
                    }
 ....
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Hubi, thats almost all my doubts. Is there a way for a thread function to return a value? On the qml/javascript side i suppose i need to use a WorkerScript
1

You've done several errors that drives you away from desired.

As it was already mentioned by @folibis and by @Hubi -- you've used C++ class names which starts from small letter. QML has problems with it.


Regarding multi-threading, there are a lots of ways to do it. It really depends on your particular tasks.

I do really recommend you to read next articles (from official Qt documentation):

Since you have signals in Qt and QML, you may implement all what you want in C++ and then just drop it to QML.

You may refer to this simple project on GitHub I've prepared for you. There is moveToThread approach implemented.

4 Comments

i'll check your project, thanks. What i want is that when i click on the button nothing is blocked and that the Qthread function returns a value from it.
@Nmaster88 just refer to shared project. There are 1) nothing blocked in UI, so you can see progress bar running etc 2) execution happens in separate thread 3) UI gets notified as soon as execution in separate thread done 4) UI gets populated with values returned from thread.
youre example seems awesome, i just have another problem that i didnt see it addressed. I need to do some processing on the qml side, that takes some time and i don't want it blocking the UI thread.
I'm going to mark this as the accepted answer, as this addresses most of what i want, i've opened another post for the qml thread processing part. stackoverflow.com/questions/56157088/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.