As you've said yourself there are quite a number of ways to do that.

One approach that i find rather elegant myself is the request handler pattern used for example by the QML API of WebEngineView.

The C++ side emits a signal that transports a request context, which is then used by the QML side to communicate the result back.

See for example http://doc.qt.io/qt-5/qml-qtwebengin...quested-signal

If you know or require that the QML side uses a modal dialog and thus a nested event loop, then you can retrieve the user's input right after the emit returns.

Qt Code:
  1. RequestContext context;
  2.  
  3. emit requestDialog(&context);
  4.  
  5. // continue in "linear" workflow
To copy to clipboard, switch view to plain text mode 

If you want to handle the nested event loop on the C++ side, it will look more like this:
Qt Code:
  1. RequestContext context;
  2.  
  3. connect(&context, &RequestContext::done, &loop, &QEventLoop::quit);
  4.  
  5. emit requestDialog(&context);
  6.  
  7. // check if dialog has not already been
  8. if (!context.isDone() {
  9. loop.exec();
  10. }
  11.  
  12. // continue in "linear" workflow
To copy to clipboard, switch view to plain text mode 

Cheers,
_