title: QML start external program: use QProcess fail build
body: <p>I am trying to build a simple application in QML that when a button was pressed an external program was lanch. I search a lot, but 99% of the solutions are similar to <a href="http://www.xargs.com/qml/process.html" rel="nofollow noreferrer">this</a>. When I compile the error is:</p>
  <pre><code>Undefined symbols for architecture x86_64:
  &quot;ProcessStarter::qt_metacall(QMetaObject::Call, int, void**)&quot;, referenced from:
    vtable for QQmlPrivate::QQmlElement&lt;ProcessStarter&gt; in main.o
  &quot;ProcessStarter::qt_metacast(char const*)&quot;, referenced from:
    vtable for QQmlPrivate::QQmlElement&lt;ProcessStarter&gt; in main.o
  &quot;ProcessStarter::staticMetaObject&quot;, referenced from:
    int qmlRegisterType&lt;ProcessStarter&gt;(char const*, int, int, char const*) in main.o
    QtPrivate::MetaObjectForType&lt;ProcessStarter*, void&gt;::value() in main.o
    QMetaTypeIdQObject&lt;ProcessStarter*, 8&gt;::qt_metatype_id() in main.o
  &quot;ProcessStarter::metaObject() const&quot;, referenced from:
    vtable for QQmlPrivate::QQmlElement&lt;ProcessStarter&gt; in main.o
  &quot;typeinfo for ProcessStarter&quot;, referenced from:
    typeinfo for QQmlPrivate::QQmlElement&lt;ProcessStarter&gt; in main.o
  &quot;vtable for ProcessStarter&quot;, referenced from:
    ProcessStarter::ProcessStarter(QObject*) in main.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  ld: symbol(s) not found for architecture x86_64
  clang: error: linker command failed with exit code 1 (use -v to see invocation)
  </code></pre>
  <p>The code of main.cpp is:</p>
  <pre><code>#include &lt;QGuiApplication&gt;
  #include &lt;QQmlApplicationEngine&gt;
  
  #include &lt;QProcess&gt;
  #include &lt;QVariant&gt;
  #include &lt;QQmlContext&gt;
  
  class ProcessStarter : public QProcess
  {
      Q_OBJECT
  
  public:
      ProcessStarter(QObject *parent = 0) : QProcess(parent) { }
      virtual ~ProcessStarter() = default;
  
      Q_INVOKABLE void start(const QString &amp;program, const QVariantList &amp;arguments)
      {
          QStringList args;
  
          // convert QVariantList from QML to QStringList for QProcess
  
          for (int i = 0; i &lt; arguments.length(); i++)
              args &lt;&lt; arguments[i].toString();
  
          QProcess::start(program, args);
      }
  
      Q_INVOKABLE QByteArray readAll() {
          return QProcess::readAll();
      }
  
  };
  
  int main(int argc, char *argv[])
  {
      QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
  
      QGuiApplication app(argc, argv);
  
      qmlRegisterType&lt;ProcessStarter&gt;(&quot;Process&quot;, 1, 0, &quot;ProcessStarter&quot;);
  
      QQmlApplicationEngine engine;
      const QUrl url(QStringLiteral(&quot;qrc:/main.qml&quot;));
      QObject::connect(&amp;engine, &amp;QQmlApplicationEngine::objectCreated,
                       &amp;app, [url](QObject *obj, const QUrl &amp;objUrl) {
          if (!obj &amp;&amp; url == objUrl)
              QCoreApplication::exit(-1);
      }, Qt::QueuedConnection);
      engine.load(url);
  
      return app.exec();
  }
  </code></pre>
  <p>Instead the main.qml is:</p>
  <pre><code>import QtQuick 2.12
  import QtQuick.Controls 2.0
  import QtQuick.Window 2.12
  
  import Process 1.0
  
  Window {
      visible: true
      width: 640
      height: 480
      title: qsTr(&quot;Hello World&quot;)
  
      ProcessStarter {
          id: process
          onReadyRead: console.info(readAll())
      }
  
      Button {
          onClicked: {
              process.start(&quot;../prova&quot;, [ &quot;-a&quot;, &quot;-b&quot;])
          }
      }
  
  }
  </code></pre>
  <p>I can't understand where is the mistake!
  Regards
  Marco</p>