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..