Q_PROPERTY должна быть полностью определенной ошибкой в Qt 6
В Qt 5 можно было использовать такой код:
// 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
}
Теперь я пытаюсь преобразовать проект в Qt 6, но приведенный выше код не работает в сгенерированном файле «debug\moc_Test.cpp» с этим сообщением об ошибке:
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
Замена прямого определения класса прямым включением заголовка работает:
// Test.h
#include <QObject>
#include <QMetaObject>
#include "LanguageModel.h" //class LanguageModel;
class Test : public QObject
{
Q_OBJECT
Q_PROPERTY(LanguageModel*, ...)
public:
};
Как я могу продолжать использовать определения классов вместо включения заголовков в Qt 6?
С уважением,
2 ответа
Я только что спросил здесь, на форуме Qt, так как сегодня у меня была такая же проблема с использованием Models. Мне проблематично включать заголовок. VRonin дал мне два решения:
- Q_MOC_INCLUDE, чтобы включить заголовок только для файла moc:
// Test.h
#include <QObject>
#include <QMetaObject>
Q_MOC_INCLUDE("LanguageModel.h")
class Test : public QObject
{
Q_OBJECT
Q_PROPERTY(LanguageModel*, ...)
public:
};
- Q_DECLARE_OPAQUE_POINTER: чтобы сообщить Qt, что мы хотим сохранить непрозрачный указатель
// 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:
};
Лично я предпочел бы второй вариант, он может сэкономить время компиляции. Я добавил макрос на тот случай, если вы будете использовать его в нескольких объектах одного проекта.
Я не эксперт, но похоже, что это требуется с Qt 6.0 из-за статического утверждения. Доказательство: https://embeddeduse.com/2021/01/17/migrating-a-harvester-hmi-from-qt-5-12-to-qt-6-0/ (глава «Ошибка: недопустимое применение» sizeof 'в неполный тип' IntegerRangeModel '')