简体   繁体   English

在 QML 可访问的 C++ QObject 子类中创建成员变量?

[英]Creating member variable in C++ QObject subclass accessable from QML?

Say I have a QObject subclass Foo defined in C++:假设我在 C++ 中定义了一个QObject子类Foo

class Foo : public QObject {
    Q_OBJECT
public:
    /* ... */
};

and say I attach it to the root context of a QQmlApplicationEngine as like:并说我将它附加到QQmlApplicationEngine的根上下文中,如下所示:

Foo foo;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("foo", (QObject*)&foo);

so now I can call a Q_INVOKABLE member function (or slot it seems) of Foo , say called doStuff() , from QML with the call foo.doStuff() :所以现在我可以通过调用 foo.doStuff() 从 QML 调用FooQ_INVOKABLE成员 function (或似乎是插槽),例如称为doStuff() foo.doStuff()

Item {
   onWhatever: { foo.doStuff(); }
}

Is it possible to define as well a member variable on Foo in C++ in such a fashion that it is visible in QML and when that member variable changes any usages of it in QML are also updated?是否可以在 C++ 中的Foo上定义一个成员变量,使其在 QML 中可见,并且当该成员变量更改时,它在 QML 中的任何用法也都更新了?

As in:如:

class Foo : public QObject {
    Q_OBJECT
public:

    Q_??? int bar = 40;
};

In QML:在 QML 中:

Item {
    width: foo.bar + 100
}

So initially the width of this item is 140 , and then later in C++:所以最初这个项目的宽度是140 ,然后是 C++:

foo.bar = 80

And now the width of the item automatically changes to 180现在项目的宽度自动更改为180

Is there something that does what I'm trying to do above?有什么可以做我上面想做的事情吗? ( Q_??? ) Q_???

You have to create a Q_PROPERTY:您必须创建一个 Q_PROPERTY:

#ifndef FOO_H
#define FOO_H

#include <QObject>

class Foo : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int bar READ bar NOTIFY barChanged)
public:
    explicit Foo(QObject *parent = nullptr);
    int bar() const;
    void setBar(int bar);
    Q_INVOKABLE void doStuff();
Q_SIGNALS:
    void barChanged(int bar);
private:
    int m_bar;
};

#endif // FOO_H
#include "foo.h"

Foo::Foo(QObject *parent) : QObject(parent), m_bar(40){}

int Foo::bar() const{
    return m_bar;
}

void Foo::setBar(int bar){
    if (m_bar == bar)
        return;
    m_bar = bar;
    emit barChanged(m_bar);
}

void Foo::doStuff()
{
    setBar(80);
}

With the above, the "bar" property is readOnly from QML, if you want it to be writable then you must also expose the setter:有了上面,“bar”属性从 QML 是只读的,如果你希望它是可写的,那么你还必须公开 setter:

Q_PROPERTY(int bar READ bar WRITE setBar NOTIFY barChanged)

I wrote a macro so this can be done with one line:我写了一个宏,所以这可以用一行来完成:

PROPERTY(int, bar)

The definition is:定义是:

#define PROPERTY(type, name)                                            \
  Q_PROPERTY(type name READ name WRITE set_##name NOTIFY name##Changed) \
 public:                                                                \
  type name() { return _property_member_##name; }                       \
  void set_##name(type _in) {                                           \
    if (_property_member_##name == _in) return;                         \
    _property_member_##name = _in;                                      \
    name##Changed(_property_member_##name);                             \
  }                                                                     \
  Q_SIGNAL void name##Changed(type name);                               \
                                                                        \
 private:                                                               \
  type _property_member_##name;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM