ouni
ouni

Reputation: 3373

How to make a custom C++ class a QML Type?

I'm trying to push a simple struct, from C++, over to QML, but I can't seem to register it:

messages.h

#pragma once

#include <QString>
#include <QMetaType>

struct Ticket {
  Q_GADGET
  Q_PROPERTY(QString name MEMBER name)
  Q_PROPERTY(QString description MEMBER description)

  public:
  QString name;
  QString description;
};
Q_DECLARE_METATYPE(Ticket);

and I am making it available to QML:

main.cpp

#include <QtWidgets>

#include "MyWindow.h"
#include "messages.h"

int main(int argc, char *argv[])
{
  QApplication app(argc, argv);
  qmlRegisterType<Ticket>("myself", 1, 0, "Ticket");
  MyWindow the_window;
  the_window.show();

  return app.exec();
}

EDIT: including QML for reference

import QtQuick.Layouts 1.11
import QtQuick 2.11

RowLayout {
  id: layout
  property var tickets

  onTicketsChanged: {
    console.log("dum dum dum");
  }
}

When compiling, I get the following error:

/Users/myself/lib/Qt/5.11.2/clang_64/lib/QtQml.framework/Headers/qqmlprivate.h:101:24: error: only virtual member
      functions can be marked 'override'
        ~QQmlElement() override {
                       ^
/Users/myself/lib/Qt/5.11.2/clang_64/lib/QtQml.framework/Headers/qqmlprivate.h:107:50: note: in instantiation of
      template class 'QQmlPrivate::QQmlElement<Ticket>' requested here
    void createInto(void *memory) { new (memory) QQmlElement<T>; }
                                                 ^
/Users/myself/lib/Qt/5.11.2/clang_64/lib/QtQml.framework/Headers/qqml.h:292:33: note: in instantiation of function
      template specialization 'QQmlPrivate::createInto<Ticket>' requested here
        sizeof(T), QQmlPrivate::createInto<T>,
                                ^
/Users/myself/dev/my_project/src/MyWindow.cpp:69:3: note: in instantiation of function template specialization
      'qmlRegisterType<Ticket>' requested here
  qmlRegisterType<Ticket>("myself", 1, 0, "Ticket");
  ^
1 error generated.

Is there a way, to make the Ticket struct available in my QML, so that I can push values from C++ to QML? Or, is there a way to find out what the virtual member override error means, in the context of qmlRegisterType?

Upvotes: 0

Views: 1760

Answers (1)

deW1
deW1

Reputation: 5660

You can't with Q_GADGETS. You can make them known (Q_DECLARE_METATYPE), however you can't register them as QML type. Once they're known you can use them, but you can't create them on the QML side.

One way to work around this is for example having a helper class (singleton or context property) with a (static) member function returning an instance of your gadget.


If you want to be able to also create them you have to use Q_OBJECT macro and inherit from QObject instead (note Q_DECLARE_METATYPE requires a pointer then).

Upvotes: 2

Related Questions