4

在我正在处理的代码中,我需要Q_PROPERTY通过一个集成从私有成员公开QWidget。像这样的东西会很好:

class MyWidget: public QWidget{
   Q_OBJECT
   Q_PROPERTY(QString headerText MEMBER myLabel.text NOTIFY QLabel::notify)

private:
   QLabel myLabel
}

是否可以这样做以及如何做?还是我必须手动编写所有的 get/set 方法?

4

2 回答 2

2

您必须编写自己的 getter/setter:

QString getText()const{ return myLabel.text();}
void setText( const QString& s){ myLabel.setText(s);}

在你可以为它定义一个 Q_PROPERTY 之后:

Q_PROPERTY( QString headerText READ getText WRITE setText)

注意:对于某些版本的 Qt,您可能会发现一些技巧有效,但它们可能会在以下版本中停止工作。出于这个原因,坚持常见/标准行为可能会更好。

编辑:

为了给这个答案添加一点形式主义,这里有一个相关的错误:

https://bugreports.qt.io/browse/QTBUG-47695?jql=text%20~%20%22Q_PROPERTY%20member%22

总结:在 Qt<=5.4 中,可以在 Q_PROPERTY MEMBER 参数中使用结构成员。此功能“偶然工作”,从现在开始不再支持。

于 2017-02-20T15:11:12.417 回答
0

如果我们不想公开 Q_PROPERTY,OP 希望避免手动编写 getter/setter 对的样板文件。

我对此没有解决方案,但我仍然对问题的“私人成员”方面感兴趣。

就我而言,我来到这里是因为我想从所有其他代码中隐藏这些必需的设置器,除了Qt 绑定代码。

根据经验,使用 Qt 5.12,以下内容对我有用:

   class HolderOfSomeInteger : public QObject {
     Q_OBJECT

     Q_PROPERTY(int someInt
                READ GetInt
                NOTIFY someIntChanged)

    signals:
     void someIntChanged();

    private:  // <--- private section
     // My own other classes cannot access this, but 
     // the QML binding works as expected anyhow.
     int GetInt() const { return some_integer; }

     int some_integer = 0;
   };

因此,除了保持int数据成员的some_integer私密性之外,我显然也可以简单地将GetInt()getter 放在该private部分中。

但是,正如@adrian-maire 在https://stackoverflow.com/a/42348046/10278中所说,“对于某些 Qt 版本,您可能会发现一些技巧有效,但它们可能会在以下版本中停止工作。”

正如这个 Qt 属性系统文档今天看起来一样,它只说

“如果未指定 MEMBER 变量,则需要 READ 访问器函数。它用于读取属性值。理想情况下,const 函数用于此目的,它必须返回属性的类型或对该类型的 const 引用。”

它没有说明访问器函数必须是公共的还是私有的。


我又挖了一些,我想我发现了为什么属性绑定仍然可以与私有 getter 一起使用。

Q_OBJECT宏声明您的类具有方法qt_metacallqt_static_metacall. QtMOC然后生成这些方法的主体。

属性绑定是使用这些方法完成的。由于这些方法是您的类的成员,它们(当然)甚至可以调用private您的类提供的成员函数。

于 2019-06-20T21:40:04.140 回答