![](/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.