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 дал мне два решения:

  1. 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:
};
  1. 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 '')

Другие вопросы по тегам