![](/img/trans.png)
[英]What is the right way for an object to have a collection of a QObject derived class?
[英]What are all the requirements of a QObject derived class?
我正在使用 Qt 框架处理我的第一个重要项目,并帮助保持文档之间的一致性并确保我不会忘记一些小要求,我决定制作一个模板文档来展示成员函数、宏等. 需要继承 QObject。 我还希望能够充分利用 Meta Object 系统。 我是否遗漏了什么或误解了什么? 如有必要,也可以随意给予任何一般的 C++ 批评。
我特别关心是否包含复制构造函数的问题。 仅对于不是从 QObject 派生的类才需要吗?
要求(链接到我从中获得要求的文档)
模板 Header
// Include guards #ifndef CLASSNAME_H #define CLASSNAME_H // Include statements #include <QObject> #include <Th> // Enum definition enum E{ E0, E1, E2 }; // Q_ENUM Macro Q_ENUM(E) // Class declaration class ClassName: public QObject { // Q_OBJECT Macro Q_OBJECT // Q_PROPERTY Macros Q_PROPERTY(T* memberA READ memberA WRITE setMemberA NOTIFY memberAChanged) Q_PROPERTY(int memberB READ memberB WRITE setMemberB NOTIFY memberBChanged) Q_PROPERTY(E memberC READ memberC WRITE setMemberC RESET resetMemberC) public: // Constructors and Destructor ClassName(QObject *parent = nullptr); ClassName() = default; ClassName(const ClassName&) = default; ~ClassName(); // Getters T* memberA() const {return m_memberA;} int memberB() const {return m_memberB;} E memberC() const {return m_memberC;} // Setters void setMemberA(T* newA); void setMemberB(int newB); void setMemberC(E newC); signals: void memberAChanged(T*); void memberBChanged(int); public slots: void resetMemberC(); private slots: private: // Data Members T* m_memberA; int m_memberB; E m_memberC; }; // Meta Object Type Declaration Q_DECLARE_METATYPE(TypeName); // End include guard #endif // CLASSNAME_H
伴随这个 header 的源文件可能是微不足道的,所以我不会在这里包含它。 尽管如果有人认为演示某些要求或功能会有所帮助,我很乐意将其写出来。
正如 Jeremy Friesner 所建议的那样,要求并不那么严格。 情况更像是这样的:
只有当您需要 class 与 QML 代码互操作时,才真正需要 Q_PROPERTY/Q_INVOKABLE 接口。
至于您的另一个问题,是的,这是 QObjects 和非 QObjects 之间的重要区别。 元类型必须是可复制的,这就是您手动声明为元类型的类型需要这样做的原因,也是系统改为使用 QObject 类型指针的原因,这些指针本身不可复制。 一个最小的 QObject 声明可以这样开始:
#ifndef CLASSNAME_H #define CLASSNAME_H #include <QObject> // Enums in the global namespace cannot be registered; they must be enclosed // in a class and registered with Q_ENUM, or in a namespace declared as // Q_NAMESPACE and registered with Q_ENUM_NS class ClassName: public QObject { Q_OBJECT public: // Default constructor, with explicit specifier to prevent accidental // implicit conversion from a QObject* explicit ClassName(QObject *parent = nullptr); }; // ClassName* is automatically declared as a metatype #endif // CLASSNAME_H
一般来说,我推荐“ 零规则”:如果可能,不要声明析构函数,也不要声明任何复制和移动操作,并将它们留给编译器。 当然,如果您有时间,我也推荐那里的所有其他指南
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.