1

I created an interface has a ListView and two Buttons. When click on Scan button it will call to C++ and make change to the model of ListView. After that C++ will emit signal to inform model is changed therefore ListView in QML will update with new model. I want to make BusyIndicator running during that process. How can i do that ?.

I saw a few solutions on stackoverflow like this one: BusyIndicator does not show up but none of them worked for my case.

Can anyone help me ? Thanks.

Here is my qml code:

import QtQuick 2.5
import QtQuick.Layouts 1.3
import Qt.labs.controls 1.0

Rectangle
{
    objectName: "bluetoothPage"
    anchors.fill: parent

    property var bluetoothDataModel: messageFromApp.bluetoothData
    onBluetoothDataModelChanged: listView.update()

    signal qmlScanButtonSignal()
    signal qmlDisconnectButtonSignal()

    ColumnLayout
    {
        anchors.fill: parent
        spacing: 6

        RowLayout
        {
            Layout.fillWidth: true

            Text
            {
                Layout.fillWidth: true
                text: "Connect with ECU"
                font.bold: true
                font.pixelSize: 20
            }

            BusyIndicator
            {
                id: busyIndicator
                Layout.preferredWidth: 30
                Layout.preferredHeight: 30
                running: false
                visible: false
            }
        }

        GroupBox
        {
            Layout.fillHeight: true
            Layout.fillWidth: true
            title: qsTr("Available device:")

            ListView
            {
                id: listView
                anchors.fill: parent
                model: bluetoothDataModel
                delegate: Component
                          {
                              Item
                              {
                                    width: parent.width
                                    height: 40
                                    Column
                                    {
                                        Text { text: "Name:" + model.modelData.name }
                                        Text { text: "Number:" + model.modelData.macAddress }
                                    }
                                    MouseArea
                                    {
                                        anchors.fill: parent
                                        onClicked: listView.currentIndex = index
                                    }
                               }
                           }
                highlight: Rectangle
                           {
                                color: "blue"
                           }
            }
        }

        RowLayout
        {
            Layout.fillWidth: true
            Layout.preferredHeight: 10

            Button
            {
                Layout.fillHeight: true
                Layout.fillWidth: true
                text: "Scan"
                onClicked: qmlScanButtonSignal()
            }

            Button
            {
                Layout.fillHeight: true
                Layout.fillWidth: true
                text: "Disconnect"
                onClicked: qmlDisconnectButtonSignal()
            }
        }
    }

}
Community
  • 1
  • 1
user2652023
  • 197
  • 2
  • 16

1 Answers1

1

Only this solution worked for me in my case. However, like everybody said using QCoreApplication::processEvents() is really bad practice. I also try to using QThread but it got crash when emitted signal inside thread. If you guy have any futher solutions, please let me now. I'm really appreciate. Thanks.

QML

BusyIndicator {
    running: CPPModule.busy
}

CPP

void CPPModule::setBusy(const bool &busy)
{
    m_busy = busy;
    emit busyChanged();
}
void CPPModule::InsertIntoDB()
{
    setBusy(true);
    QThread::msleep(50);
    QCoreApplication::processEvents();
    /*
    very Long Operation
    */
    setBusy(false);
}

Another solution is this:

Timer {
   id: myTimer
   interval: 1
   onTriggered: {
        app.someLongRunningFunction();
        myActivityIndicator.visible = false;
   }
}

Butoon{
    ....
    onClicked: {
        myActivityIndicator.visible=true;
        myTimer.start();
    }
} 
user2652023
  • 197
  • 2
  • 16