代码之家  ›  专栏  ›  技术社区  ›  Zeta

如何记录与Q\U属性同名的访问器函数?

  •  7
  • Zeta  · 技术社区  · 8 年前

    TL;DR(灾难恢复): 如何为与用声明的属性具有相同名称的访问者生成doxygen文档 Q_PROPERTY ?


    Qt的 property system 可以在给定属性上使用Qt的元对象系统:

    // example class and documentation
    class Widget : public QObject {
      Q_OBJECT
      Q_PROPERTY(int size READ size WRITE setSize NOTIFY sizeChanged)
    
    public:
      Widget(QObject * parent = nullptr) : QObject(parent){}
      int size() const;
    
    public slots:
      void setSize(int new_size);
    
    signals:
      void sizeChanged(int); //!< signals a size change
    
    private:
      int m_size = 0; //!< the Widget's size, see #size.
    };
    

    如果现在在实现中使用doxygen

    //! @property size is the size of our widget
    
    //! @brief Set the widget's size to @a new_size.
    void Widget::setSize(int new_size) { 
      if(new_size != m_size) {
        m_size = new_size; 
        emit sizeChanged(m_size);
      }
    }
    
    //! @brief Returns the widget's size.
    int Widget::size() const {
      return m_size;
    }
    

    只有 setSize 正确生成的文档。 size() 的文档被误认为 财产的 文档上述代码的作用就像

    //! @property size
    //! @brief Returns the widget's size.
    int Widget::size() const {
      return m_size;
    }
    

    已使用。也不 @fn Widget::size()const 其他任何doxygen特别命令似乎也没有帮助: 大小() 的生成文档保持为空,并以 size (属性)文档。

    这是一个bug,还是我遗漏了什么?

    2 回复  |  直到 8 年前
        1
  •  7
  •   Zeta    7 年前

    这是一个 known bug 或者说是未实现的功能。到目前为止,如果属性和getter具有相同的名称,则无法记录它们。getter的文档总是以属性的文档结尾。

    原因是 doxygen findmember 实施如果您使用 doxygen -d findmembers 你可以看到两者 size (财产)和 size() (功能)“匹配”:

    findMemberDocumentation(): root->type=`int' root->inside=`' root->name=`Widget::size' root->args=`() const ' section=6000000 root->spec=0 root->mGrpId=-1
    findMember(root=0x197efe0,funcDecl=`int Widget::size() const ',related=`',overload=0,isFunc=1 mGrpId=-1 tArgList=(nil) (#=0) spec=0 lang=200
    findMember() Parse results:
      namespaceName=`'
      className=`Widget`
      funcType=`int'
      funcSpec=`'
      funcName=`size'
      funcArgs=`() const'
      funcTempList=`'
      funcDecl=`int Widget::size'
      related=`'
      exceptions=`'
      isRelated=0
      isMemberOf=0
      isFriend=0
      isFunc=1
    
    1. funcName=`size'
    2. member name exists (2 members with this name)
    3. member definition found, scope needed=`Widget' scope=`Widget' args=`' fileName=/tmp/test/example.cpp
    4. class definition Widget found
    5. matching `'`() const' className=Widget namespaceName=
    6. match results of matchArguments2 = 1
    

    你甚至可以用另一个非- const 变种 int size() 。您将得到三个同名的成员。Doxygen目前无法处理具有相同名称的属性和函数,并且在本例中不记录getter。

    如果不需要属性文档,可以禁用 Q_PROPERTY 中的宏 Doxyfile (作为 documented ):

    ENABLE_PREPROCESSING  = YES
    MACRO_EXPANSION       = YES
    PREDEFINED            = Q_PROPERTY(x)= 
    

    这样lexer就不会扫描 Q\u属性

        2
  •  0
  •   albert    8 年前

    正如承诺的那样: 与原始代码的不同之处在于,文档不是放在实现文件中,而是放在include文件中。

    包含文件:

    // example class and documentation
    class Widget : public QObject {
      Q_OBJECT
      //! size is the size of our widget
      Q_PROPERTY(int size READ size WRITE setSize NOTIFY sizeChanged)
    
    public:
      //! Set the widget's size to @a new_size.
      Widget(QObject * parent = nullptr) : QObject(parent){}
      //! Returns the widget's size.
      int size() const;
    
    public slots:
      void setSize(int new_size);
    
    signals:
      void sizeChanged(int); //!< signals a size change
    
    private:
      int m_size = 0; //!< the Widget's size, see #size.
    };
    

    实施文件:

    void Widget::setSize(int new_size) {
      if(new_size != m_size) {
        m_size = new_size;
        emit sizeChanged(m_size);
      }
    }
    
    int Widget::size() const {
      return m_size;
    }
    

    doxygen配置文件中的差异( Doxyfile ,可能几个到多个设置为是):

    EXTRACT_ALL            = YES
    EXTRACT_PRIVATE        = YES
    EXTRACT_PACKAGE        = YES
    EXTRACT_STATIC         = YES
    EXTRACT_LOCAL_METHODS  = YES
    EXTRACT_ANON_NSPACES   = YES