c++qtqmlqt-quickqqmlengine

Qt Quick - How to use a c++ class inheriting from QQuickPaintedItem in a qml interface?


I'm newbie with Qt 5.13.0. In a Visual Studio 2019 project, I need to display a custom painted item inherited from the QQuickPaintedItem class in a qml interface. The custom item is written in a c++ class named WQTMessageItem, which is declared as follow:

class WQTMessageItem : public QQuickPaintedItem
{
    Q_OBJECT
    Q_PROPERTY(bool rightAligned READ isRightAligned WRITE setRightAligned NOTIFY rightAlignedChanged)

    signals:
        void rightAlignedChanged();

    public:
        WQTMessageItem(QQuickItem* parent = 0);

        void paint(QPainter* painter);

        bool isRightAligned();
        void setRightAligned(bool rightAligned);

    private:
        bool m_RightAligned;
};

On the c++ side, I'm trying to declare the above class to the qml engine this way:

QQmlContext* pContext = engine.rootContext();
std::unique_ptr<WQTMessageItem> pMessageItem(new WQTMessageItem());
pContext->setContextProperty("WQTMessageItem", pMessageItem.get());
pMessageItem.release();

And finally, I'm trying to use the above custom item in a ListView declared in a qml file, this way:

ListView
{
    anchors.bottom: controls.top
    anchors.bottomMargin: 2
    anchors.top: parent.top
    id: balloonView

    delegate: WQTMessageItem
    {
        anchors.right: index % 2 == 0 ? undefined : parent.right
        height: 60
        rightAligned: index % 2 == 0 ? false : true
        width: balloonWidth
    }

    model: balloonModel
    spacing: 5
    width: parent.width
}

Unfortunately this doesn't work. My application compiles and links, but closes immediately on running, with the following error message:

QQmlApplicationEngine failed to load component
qrc:/main.qml:33 WQTMessageItem is not a type

I tried to find a solution by myself, without success. Can someone explain me how I should modify my above code to allow it to work?


Solution

  • You have to register the C++ type in the QML system using the qmlRegisterType function.
    An example may be found here.

    The setContextProperty method is intended to export a value (not a type) from C++ to QML.