0

I am in the process of learning of coding QtQuick applications using C++ on the background. My plan is to write as most as possible code in QtQuick (QML), but there is one thing I could not find, so I decided to use C++. Basically, I need to create an app which provides an user with certain widgets and one button. Upon clicking on the button an CLI command is created and called. I can create this CLI command using javascript, but I did not find a way how to execute this command, so I decided for C++.

The plan is to register a signal in on the button in QML and connect this signal with a slot in C++. I opened the QML documentation where I found several helpful examples. My code of an testing app contains two source files:

main.qml:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import "scripts.js" as Logic


ApplicationWindow {
    title: qsTr("Hello World")
    width: 640
    height: 480
    visible: true
    minimumHeight: 480
    minimumWidth: 640


    ColumnLayout{
        spacing: 2
        height: parent.height - 100
        width: parent.width

        GridLayout {
            id: grid
            columns: 3

            Label { text: "Vstupni soubor";  }
            TextField {
                id: input_file_field
            }
            Button {
                text: "..."
                onClicked: fileDialogInputFile.open()
            }


            Label { text: "Vystupni adresar";  }
            TextField {id: output_dir_field}
            Button {
                text: "..."
                onClicked: fileDialogOutputDir.open()
            }

            CheckBox{
                id: opt1
                text: "Volba 1"
            }

            CheckBox{
                id: opt2
                text: "Volba 2"
            }

            CheckBox{
                id: opt3
                text: "Volba 3"
            }

        }

        Button {

            signal qmlSignal(string msg)
            objectName: "myButton"

            text: "Analyzuj"
            onClicked: {
                qmlSignal("Hello from QML")
                console.log("Nahodne cislo " + Logic.func())
            }
        }

    }


    TextArea {
        id: log_output
        width: parent.width
        height: 100
        y: parent.height - 100
        readOnly: true
        text: "Log zprav";
    }

    FileDialog {
        id: fileDialogInputFile
        title: "Please choose a file"
        onAccepted: {
            input_file_field.text = fileDialogInputFile.fileUrl
        }
    }

    FileDialog {
        id: fileDialogOutputDir
        title: "Please select output directory"
        selectFolder: true
        onAccepted: {
            output_dir_field.text = fileDialogOutputDir.fileUrl
            console.log("You chose: " + fileDialogOutputDir.fileUrl)
        }
    }


}

main.cpp:

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QDebug>
#include <QObject>

class MyClass : public QObject
{
    Q_OBJECT

public slots:
    void cppSlot(const QString &msg) {
        qDebug() << "Called the C++ slot with message:" << msg;
    }
};


int main(int argc, char *argv[]) {
    qDebug() << "Hello World - main!";

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    MyClass myClass;
    QObject *win = engine.rootObjects()[0];
    QObject *item = win->findChild<QObject*>("myButton");

    QObject::connect(item, SIGNAL(qmlSignal(QString)),
                     &myClass, SLOT(cppSlot(QString)));

    return app.exec();
}

Program can be compiled and run. When I run the program, I can see this on console:

QML debugging is enabled. Only use this in a safe environment.
Hello World - main!
QObject::connect: No such slot MyClass::cppSlot(QString) in ../pokus/main.cpp:30
QObject::connect:  (sender name:   'myButton')

Which means, the program is running but can not connect cppSlot onto the signal generated by my button. The problem I have is that I followed QML manual, and blogs deal with most sophisticated problems, i.e., I spent a day by googling without any outcome..

1 Answers1

0

Your code doesn't compile:

debug/main.o: In function `MyClass::MyClass()':
/home/micurtis/dev/test/guitest/main.cpp:6: undefined reference to `vtable for MyClass'

If I #include "main.moc" and remove the references to Logic.js, it works for me when I click on "Analyzuj":

    // ...
    return app.exec();
}

#include "main.moc"

Output:

Starting /home/micurtis/dev/test/guitest/guitest...
QML debugging is enabled. Only use this in a safe environment.
Hello World - main!
Called the C++ slot with message: "Hello from QML"
/home/micurtis/dev/test/guitest/guitest exited with code 0
Mitch
  • 23,716
  • 9
  • 83
  • 122