【问题标题】:How do I document an accessor function with the same name as a Q_PROPERTY?如何记录与 Q_PROPERTY 同名的访问器函数?
【发布时间】:2018-08-17 22:51:15
【问题描述】:

TL;DR:如何为与Q_PROPERTY 声明的属性同名的访问器生成 doxygen 文档?


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 的 文档。上面的代码就像

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

被使用了。 @fn Widget::size()const 或任何其他 doxygen 特殊命令似乎都没有帮助:size() 生成的文档保持空白,并最终出现在 size(属性)文档中。

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

【问题讨论】:

  • doxygen 的哪个版本?或许配置章节中的示例,段落示例可以给你一个提示。请参阅预定义部分。
  • @albert doxygen --version 是 1.8.11。 doxygen 手册部分中的“技巧”有效,但会一起删除属性文档,无论我是否想要 both。但我猜这很可能是not possible
  • 我认为基本问题可能通过以下方式发出信号:“.../aa.cpp:6: warning: member with no name found.”,这是属性文档行。我还没有看到解决方案。 (在消息周围的 doxygen 代码中存在以下内容:“// 这不应该被调用”。
  • 看起来在包含文件/类定义中记录函数和属性时可以这样://!是我们的小部件 Q_PROPERTY(int size READ size WRITE setSize NOTIFY sizeChanged) 和 //! 的大小返回小部件的大小。 int size() 常量;
  • 您是否尝试过在 .h 文件而不是 .cpp 文件中记录 Q_PROPERTY 的建议?

标签: c++ qt doxygen


【解决方案1】:

这是一个known bug 或者说是未实现的功能。截至今天,如果属性和吸气剂具有相同的名称,则无法记录它们。 getter 的文档将始终位于属性的文档中。

原因是doxygenfindmember 实现。如果您使用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() 解析结果: 命名空间名称=`' 类名=`小部件` funcType=`int' funcSpec=`' funcName=`大小' funcArgs=`() 常量' funcTempList=`' funcDecl=`int Widget::size' 相关=`' 例外=`' 相关=0 isMemberOf=0 是朋友=0 isFunc=1 1. funcName=`大小' 2. 会员名存在(2名同名会员) 3. 找到成员定义,scope required=`Widget' scope=`Widget' args=`' fileName=/tmp/test/example.cpp 4.类定义Widget找到 5。匹配 `'`() const' className=Widget namespaceName= 6. matchArguments2 = 1的匹配结果

您甚至可以使用另一个非const 变体int size() 来重现它。您最终将得到三个具有相同名称的成员。 Doxygen 目前无法处理同名的属性和函数,并且在这种情况下没有记录 getter。

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

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

这样词法分析器就不会扫描Q_PROPERTY

【讨论】:

    【解决方案2】:

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

    包含文件:

    // 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,可能有几个到多个设置为 YES):

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

    【讨论】:

    • 虽然“按照承诺”,但答案本身并不包含差异。请在答案中包含 all 解释,因为评论链随时可能被删除。
    • 另外,这仅在标题中记录了size()(方法)时才有效,答案中也应提及。
    猜你喜欢
    • 2021-12-21
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多