QML start external program: use QProcess fail build
Solved
QML and Qt Quick
-
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 -
In addition to suggestion by the @J-Hilk , remove the build directory & start fresh build.