Call C++ function from QML

Hello.
I just want create an application with Button. Each Button call an C++ function.
I found some tutoriales
https://sailfishos.org/wiki/Tutorial_-_Combining_C%2B%2B_with_QML
https://decovar.dev/blog/2016/07/18/cpp-backend-qml/

But no one works.
My class declaration :`include

class socketRPI : public QObject
{
Q_OBJECT
//Q_PROPERTY(int ArretIN READ ArretIN)
public:
explicit socketRPI(QObject *parent = nullptr);
Q_INVOKABLE int ArretIN();`
My main.cpp :

#include "qml/pages/socketrpi.h"

int main(int argc, char *argv[])
{
QScopedPointer app(SailfishApp::application(argc, argv));
QScopedPointer v(SailfishApp::createView());
qmlRegisterType(“com.example”, 1, 0, “socketRPI”);
v->setSource(SailfishApp::pathTo(“qml/controleRPI.qml”));
v->show();
return app->exec();
}
And .qml :

import QtQuick 2.0
import Sailfish.Silica 1.0
import com.example 1.0

socketRPI {
id: rpi
}
Page {
id: page

// The effective value will be restricted by ApplicationWindow.allowedOrientations
allowedOrientations: Orientation.All

// To enable PullDownMenu, place our content in a SilicaFlickable
SilicaFlickable {
    anchors.fill: parent

    // PullDownMenu and PushUpMenu must be declared in SilicaFlickable, SilicaListView or SilicaGridView
    PullDownMenu {
        MenuItem {
            text: qsTr("Show Page 2")
            onClicked: pageStack.animatorPush(Qt.resolvedUrl("SecondPage.qml"))
        }
    }

    // Tell SilicaFlickable the height of its content.
    contentHeight: column.height

    // Place our content in a Column.  The PageHeader is always placed at the top
    // of the page, followed by our content.
    Column {
        id: column

        width: page.width
        spacing: Theme.paddingLarge
        PageHeader {
            title: qsTr("Controle RPI")
        }
        Label {
            x: Theme.horizontalPageMargin
            text: qsTr("Control HiFi")
            color: Theme.secondaryHighlightColor
            font.pixelSize: Theme.fontSizeExtraLarge
        }
        ButtonLayout {
            Button {
                text: "Arret CD+IN"
                onClicked: { rpi.ArretIN() }
            }
            Button {
                text: "Marche CD+IN"
            }
            Button {
                text: "Tuner ON-OFF"
            }
        }
    }
}

}

I’d tried some placement of ‘socketRPI’ block but, always error :
‘Syntax error’ or ‘unkwnow property’
Thank for your help

In QML, names of types should begin with a capital letter. Identifiers with lower case letters are interpreted as property names.

In your CPP file, you should change the line where you register the type to:

  1. Capitalize the QML type name
  2. Since qmlRegisterType is a templated function, you’ll need to pass the C++ type you’re registering as the first template argument.
 qmlRegisterType<socketRPI>(“com.example”, 1, 0, “SocketRPI”);

Secondly, you’ll need to change your QML file. You’ll need to update it to your new type name and since QML files can only have one component at the root, you’ll should adapt it to that. The latter can be done by moving the socketRPI into the Page component.

It should look like this:

import QtQuick 2.0
import Sailfish.Silica 1.0
import com.example 1.0


Page {
    id: page

    // The effective value will be restricted by ApplicationWindow.allowedOrientations
    allowedOrientations: Orientation.All

    SocketRPI {
        id: rpi
    }

    // To enable PullDownMenu, place our content in a SilicaFlickable
    SilicaFlickable {
        ...
    }
}

I hope that helps!

4 Likes

Is the key ! :blush:
Thank you for your help.

It’s my first day with QML. It’s the first language (for me) with syntax depend of first caracter case : I hate that :rage:

1 Like