Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved QML start external program: use QProcess fail build

    QML and Qt Quick
    qml qprocess build failed
    3
    4
    720
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • W
      warcomeb last edited by warcomeb

      Hi all,
      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 this. When I compile the error is:

      Undefined symbols for architecture x86_64:
      "ProcessStarter::qt_metacall(QMetaObject::Call, int, void**)", referenced from:
        vtable for QQmlPrivate::QQmlElement<ProcessStarter> in main.o
      "ProcessStarter::qt_metacast(char const*)", referenced from:
        vtable for QQmlPrivate::QQmlElement<ProcessStarter> in main.o
      "ProcessStarter::staticMetaObject", referenced from:
        int qmlRegisterType<ProcessStarter>(char const*, int, int, char const*) in main.o
        QtPrivate::MetaObjectForType<ProcessStarter*, void>::value() in main.o
        QMetaTypeIdQObject<ProcessStarter*, 8>::qt_metatype_id() in main.o
      "ProcessStarter::metaObject() const", referenced from:
        vtable for QQmlPrivate::QQmlElement<ProcessStarter> in main.o
      "typeinfo for ProcessStarter", referenced from:
        typeinfo for QQmlPrivate::QQmlElement<ProcessStarter> in main.o
      "vtable for ProcessStarter", 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)
      

      The code of main.cpp is:

      #include <QGuiApplication>
      #include <QQmlApplicationEngine>
      
      #include <QProcess>
      #include <QVariant>
      #include <QQmlContext>
      
      class ProcessStarter : public QProcess
      {
          Q_OBJECT
      
      public:
          ProcessStarter(QObject *parent = 0) : QProcess(parent) { }
          virtual ~ProcessStarter() = default;
      
          Q_INVOKABLE void start(const QString &program, const QVariantList &arguments)
          {
              QStringList args;
      
              // convert QVariantList from QML to QStringList for QProcess
      
              for (int i = 0; i < arguments.length(); i++)
                  args << 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<ProcessStarter>("Process", 1, 0, "ProcessStarter");
      
          QQmlApplicationEngine engine;
          const QUrl url(QStringLiteral("qrc:/main.qml"));
          QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                           &app, [url](QObject *obj, const QUrl &objUrl) {
              if (!obj && url == objUrl)
                  QCoreApplication::exit(-1);
          }, Qt::QueuedConnection);
          engine.load(url);
      
          return app.exec();
      }
      

      Instead the main.qml is:

      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("Hello World")
      
          ProcessStarter {
              id: process
              onReadyRead: console.info(readAll())
          }
      
          Button {
              onClicked: {
                  process.start("../prova", [ "-a", "-b"])
              }
          }
      
      }
      

      I can't understand where is the mistake! Can you help me?
      Regards
      Marco

      J.Hilk 1 Reply Last reply Reply Quote 0
      • J.Hilk
        J.Hilk Moderators @warcomeb last edited by

        @warcomeb

        You're defining a QObject class in main.cpp -> add #include "main.moc" after the class definition

        ....
            return app.exec();
        }
        #include "main.moc"
        

        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct

        Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        W 1 Reply Last reply Reply Quote 3
        • J.Hilk
          J.Hilk Moderators @warcomeb last edited by

          @warcomeb

          You're defining a QObject class in main.cpp -> add #include "main.moc" after the class definition

          ....
              return app.exec();
          }
          #include "main.moc"
          

          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct

          Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          W 1 Reply Last reply Reply Quote 3
          • dheerendra
            dheerendra Qt Champions 2022 last edited by

            In addition to suggestion by the @J-Hilk , remove the build directory & start fresh build.

            Dheerendra
            @Community Service
            Certified Qt Specialist
            http://www.pthinks.com

            1 Reply Last reply Reply Quote 1
            • W
              warcomeb @J.Hilk last edited by

              @J-Hilk Thanks for your help! It works!

              1 Reply Last reply Reply Quote 1
              • First post
                Last post