class MainView : public QQuickView
{
    Q_OBJECT
private:
    QThread *pgb_thread = nullptr;
public:
    MainView();
    void exitThread();

public slots:
    void onExecThread();
    void onStartThread();
};

MainView::MainView()
{   
    connect(this->rootObject(), SIGNAL(execThread()), this, SLOT(onExecThread()));
}

void MainView::exitThread()
{
    if(!pgb_thread) return;
    pgb_thread->requestInterruption();
    pgb_thread->quit();
    pgb_thread->wait();
}

void MainView::onExecThread()
{
    if(pgb_thread){
        if(pgb_thread->isRunning() == true) return;
        exitThread();
    }

    pgb_thread = new QThread(this);
    connect(pgb_thread, SIGNAL(started()), this, SLOT(onStartThread()), Qt::DirectConnection);
    connect(pgb_thread, SIGNAL(finished()), SLOT(deleteLater()));
    pgb_thread->start();
}

void MainView::onStartThread()
{   
    // QMLから特定のアイテムを検索する。
    // ただし、QMLとC++とのロジック分離の観点より、ルートではないアイテムを取得するのは本来好ましくない。
    // また、キーワードはobjectNameの値でありidでない点に注意！
    QQuickItem* btn = rootObject()->findChild<QQuickItem*>("btn");
    if(btn){
        QMetaObject::invokeMethod(btn, "updateText",
            Q_ARG(QVariant, QVariant::fromValue(QString("Running"))));
        return;
    }

    for(int i = 0; i < 1000; i++){
        if(QThread::currentThread()->isInterruptionRequested() == true) return;
        QThread::msleep(200);
        // プロパティを取得したい場合の例
        // int v = rootObject()->property("progressVal").toInt();
        rootObject()->setProperty("progressVal", i);
    }
}