2

使用 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 中包含标题?

问候,

4

2 回答 2

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:
};

我个人更喜欢第二种选择,它可以节省一些编译时间。我添加了宏,以防您在同一个项目的多个对象中使用它。

于 2021-09-01T12:33:18.290 回答
0

我不是专家,但由于静态断言,它看起来自 Qt 6.0 以来是必需的。证明:https ://embeddeduse.com/2021/01/17/migrating-a-harvester-hmi-from-qt-5-12-to-qt-6-0/ (章节'错误:'sizeof的无效应用'到不完整的类型'IntegerRangeModel'')

于 2021-04-05T10:13:19.727 回答