5

With Qt 5 it was possible to use code like this:

// Test.h
#include <QObject>
#include <QMetaObject>

class LanguageModel;

class Test : public QObject
{
    Q_OBJECT
    Q_PROPERTY(LanguageModel*, ...)
public:
};


// Test.cpp
#include "Test.h"
#include "LanguageModel.h"



// LanguageModel.h
#include <QObject>
#include <QMetaObject>

class LanguageModel : public QObject
{
    Q_OBJECT
}

Now I am trying to convert the project to Qt 6 but the above code fails in the generated "debug\moc_Test.cpp" file with this error message:

C:\Qt\6.1.0\msvc2019_64\include\QtCore\qmetatype.h:778: error: C2338: Type argument of Q_PROPERTY or Q_DECLARE_METATYPE(T*) must be fully defined

Replacing the class forward definition with a direct header include works:

// Test.h
#include <QObject>
#include <QMetaObject>

#include "LanguageModel.h" //class LanguageModel;

class Test : public QObject
{
    Q_OBJECT
    Q_PROPERTY(LanguageModel*, ...)
public:
};

How can I keep using class defintions instead of including the headers in Qt 6?

Regards,

Hyndrix
  • 4,282
  • 7
  • 41
  • 82

2 Answers2

4

I've just asked here on Qt forum as I had the same issue today using Models. It's problematic for me to have to include the header. Two solutions were given to me by VRonin:

  1. Q_MOC_INCLUDE to include the header only for the moc file:
// Test.h
#include <QObject>
#include <QMetaObject>
Q_MOC_INCLUDE("LanguageModel.h")

class Test : public QObject
{
    Q_OBJECT
    Q_PROPERTY(LanguageModel*, ...)
public:
};
  1. Q_DECLARE_OPAQUE_POINTER: to tell Qt we want to keep an opaque pointer
// Test.h
#include <QObject>
#include <QMetaObject>

#ifndef OPAQUE_PTR_LanguageModel
  #define OPAQUE_PTR_LanguageModel
  Q_DECLARE_OPAQUE_POINTER(LanguageModel*)
#endif // OPAQUE_PTR_LanguageModel


class Test : public QObject
{
    Q_OBJECT
    Q_PROPERTY(LanguageModel*, ...)
public:
};

Personally I would prefer the second option, it could save some compilation time. I've added the macro just in case you would use it in several objects of a same project.

Matthieu
  • 121
  • 7
0

I'm not an expert, but it looks like it's required since Qt 6.0 because of static assertion. Proof: https://embeddeduse.com/2021/01/17/migrating-a-harvester-hmi-from-qt-5-12-to-qt-6-0/ (chapter 'Error: invalid application of ‘sizeof’ to incomplete type ‘IntegerRangeModel’')