title: Blocking operation in Qt Quick
body: <p>I want to perform a long task when a button is clicked. I want this task to block the UI, because the application cannot function until the task is done. However, I want to indicate to the user that something is happening, so I have a <code>BusyIndicator</code> (that runs on the render thread) and is set to display before the operation begins. However, it never renders. Why?</p>
  
  <p><strong>main.cpp:</strong></p>
  
  <pre><code>#include &lt;QGuiApplication&gt;
  #include &lt;QQmlApplicationEngine&gt;
  #include &lt;QQmlContext&gt;
  #include &lt;QDateTime&gt;
  #include &lt;QDebug&gt;
  
  class Task : public QObject
  {
      Q_OBJECT
      Q_PROPERTY(bool running READ running NOTIFY runningChanged)
  
  public:
      Task() : mRunning(false) {}
  
      Q_INVOKABLE void run() {
          qDebug() &lt;&lt; "setting running property to true";
          mRunning = true;
          emit runningChanged();
  
          // Try to ensure that the scene graph has time to begin the busy indicator
          // animation on the render thread.
          Q_ASSERT(QMetaObject::invokeMethod(this, "doRun", Qt::QueuedConnection));
      }
  
      bool running() const {
          return mRunning;
      }
  
  signals:
      void runningChanged();
  
  private:
      Q_INVOKABLE void doRun() {
          qDebug() &lt;&lt; "beginning long, blocking operation";
          QDateTime start = QDateTime::currentDateTime();
          while (start.secsTo(QDateTime::currentDateTime()) &lt; 2) {
              // Wait...
          }
          qDebug() &lt;&lt; "finished long, blocking operation";
  
          qDebug() &lt;&lt; "setting running property to false";
          mRunning = false;
          emit runningChanged();
      }
  
      bool mRunning;
  };
  
  int main(int argc, char *argv[])
  {
      QGuiApplication app(argc, argv);
  
      QQmlApplicationEngine engine;
      Task task;
      engine.rootContext()-&gt;setContextProperty("task", &amp;task);
      engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
  
      return app.exec();
  }
  
  #include "main.moc"
  </code></pre>
  
  <p><strong>main.qml:</strong></p>
  
  <pre><code>import QtQuick 2.6
  import QtQuick.Window 2.2
  import Qt.labs.controls 1.0
  
  Window {
      width: 600
      height: 400
      visible: true
  
      Shortcut {
          sequence: "Ctrl+Q"
          onActivated: Qt.quit()
      }
  
      Column {
          anchors.centerIn: parent
          spacing: 20
  
          Button {
              text: task.running ? "Running task" : "Run task"
              onClicked: task.run()
          }
          BusyIndicator {
              anchors.horizontalCenter: parent.horizontalCenter
              running: task.running
              onRunningChanged: print("BusyIndicator running =", running)
          }
      }
  }
  </code></pre>
  
  <p>The debugging output looks correct in terms of the order of events:</p>
  
  <pre><code>setting running property to true
  qml: BusyIndicator running = true
  beginning long, blocking operation
  finished long, blocking operation
  setting running property to false
  qml: BusyIndicator running = false
  </code></pre>