0

For a while I thought that I was not able to use Qt c++ classes with qml applications, but I found this: http://doc.qt.io/qt-5/qtqml-cppintegration-definetypes.html.

Now I'm trying to create an instantiable object type. I first ran into "Qwidget: Cannot create a Qwidget without QApplication" reading online it the answer seem to be just to change QGuiApplication to QApplication, but then I get: "ASSERT: " !d->isWidget"

This is the Qt class that I'm trying to use as a qml type: http://doc.qt.io/qt-5/qlcdnumber.html.

Here is my main.cpp:

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QLCDNumber>
#include <QQuickStyle>
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    qmlRegisterType<QLCDNumber>("LCDNumber",1,0,"LCDNumber");
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    if (engine.rootObjects().isEmpty())
        return -1;


    return app.exec();
}

Here is what I'm trying to create in main.qml:

...
import LCDNumber 1.0
Window {

    ... 

    LCDNumber{
        digitCount: 3
        intValue: 1
        mode: LCDNumber.Dec
        segmentStyle: LCDNumber.Flat
        smallDecimalPoint: false
        value: 0
    }
}

Is it really possible to create a qt c++ class in qml? I'm missing something?

Felipe Centeno
  • 2,911
  • 1
  • 21
  • 39
  • 1
    http://doc.qt.io/qt-5/qtqml-tutorials-extending-qml-example.html – Alexander V Jun 14 '17 at 01:14
  • You are mixing `Qt` and `QtWidget` and `QtQuick2`. `QtWidget` and `QtQuick2` are both part of `Qt` (there is way more to `Qt` thant just those two). And just because you can't integrate `QtWidget`s to `QtQuick` does not mean, you can't integrate anything from `Qt`. Much - e.g. many models - is easily integrateable in qml. – derM - not here for BOT dreams Jun 14 '17 at 05:14

1 Answers1

2

Yes, it's possible!

In your class use the Tags Q_PROPERTY and Q_INVOKABLE to provide into QML access to properties and methods class, like this:

class NameYourClass : public QDeclarativeItem {
    Q_OBJECT
    Q_PROPERTY(int intProperty1 READ getIntProperty1 WRITE setIntProperty1)
    Q_PROPERTY(QString strProperty2 READ getStrProperty2 WRITE setStrProperty2)

private:
    int intProperty1;
    QString strProperty2;

public:
    explicit NameYourClass(QDeclarativeItem *parent = 0);
    ~NameYourClass();

    Q_INVOKABLE int getIntProperty1() const;
    Q_INVOKABLE void setIntProperty1(int value);

    Q_INVOKABLE QString getStrProperty2() const;
    Q_INVOKABLE void setStrProperty2(const QString &value);
}

Your main.cpp:

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    qmlRegisterType<NameYourClass>("IdentifierName", 1, 0, "NameYourClass");

    return app.exec();
}

Your QML file:

import IdentifierName 1.0

Rectangle {
    id: nameRectangle
    width: 999
    height: 999

    onSomethingChange: {
        execFunction();
    }

    property NameYourClass nameDesired: nameObject

    NameYourClass {
        id: nameObject
        intProperty1: 999
    }

    function execFunction() {
        var varExample;
        varExample = nameDesired.getIntProperty1();
        nameDesired.setIntProperty1(varExample);
    }
}

I do not think I've forgotten anything.

I hope it helps!

  • Do you know if there would be a way to add this functionality to an existing Qt c++ class like: "http://doc.qt.io/qt-4.8/qlcdnumber.html". Maybe using a wrapper or something of the kind? – Felipe Centeno Jun 14 '17 at 15:03
  • Class Qt only if it can be extended into a subclass. Otherwise, it is not possible. –  Jun 14 '17 at 18:55