Как использовать QThread из QML при одновременной асинхронной функции QML - PullRequest
1 голос
/ 14 мая 2019

Я ищу способ использования QThread в QML.Я хочу передать параметры в функцию QThread и вернуть из нее значение bool.

Еще одна вещь, которую я хочу со стороны QML, - не блокировать приложение, когда оно выполняет скрипт, который произойдет до вызова /выполнение QThread.

Ниже приведен пример кода:

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
}

Как это можно сделать?

Ответы [ 2 ]

2 голосов
/ 14 мая 2019

Зарегистрируйте тип правильно:

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

Создайте экземпляр вашего типа в файле 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

    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
                        }
                    }
 ....
}
1 голос
/ 14 мая 2019

Вы сделали несколько ошибок, которые отвлекают вас от желаемого.

Как уже упоминалось @folibis и @Hubi - вы использовали имена классов C ++, которые начинаются с маленькой буквы. У QML с этим проблемы.


Что касается многопоточности, существует множество способов сделать это. Это действительно зависит от ваших конкретных задач.

Я действительно рекомендую вам прочитать следующие статьи (из официальной документации Qt):

Поскольку у вас есть сигналы в Qt и QML, вы можете реализовать все, что хотите, в C ++, а затем просто перенести их в QML.

Вы можете сослаться на этот простой проект на GitHub Я подготовил для вас. Применен moveToThread подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...