0
votes

I have a C++ class Bar that holds a reference to an instance of another class Foo. When a method on Bar is called, I want to emit a QML signal on the Foo instance. I haven't coded in C++ in 20 years, and the syntax that QML uses to emit signals confuses me.

Foo.h

#include <QOpenGLFramebufferObject>
#include <QQuickFramebufferObject>
class Bar;

class Foo : public QQuickFramebufferObject {
  Q_OBJECT
public:
  Foo();
  virtual ~Foo();
signals:
  void huzzah();
private:
  Bar &bar;
};

 

Foo.cpp

#include "Foo.h"
...
class Bar: public QObject {
  Q_OBJECT
public:
  Bar();
  ~Bar();
  void SetItemAttached( QQuickItem &inItem );

public slots:
  void BeforeRender();

private:
  QQuickItem *foo;
};

void Bar::SetItemAttached( QQuickItem &inItem ) {
  foo = &inItem;
}

//************************************************
//* When this method is called I want to emit a
//* signal on foo, not on the bar instance.
//************************************************
void Bar::BeforeRender() {
  // I really want something like foo.emit(...)
  emit huzzah();
}

Foo::Foo() : bar( *new Bar() ) {
  bar.SetItemAttached( *this );
}

Foo::~Foo() {
  delete &bar;
}

How can I modify the code in BeforeRender() method above to emit a signal on foo?

The (new-to-QML) C++ programmers around me say that I must have Bar emit a dummy signal, and then connect it to a slot on Foo that emits a signal on Foo. Is this the only (or best) way?

1
You can also have Bar directly emit Foo's signal: emit foo->huzzah(). However, if you store Foo as a QQuickItem (foo's type is QQuickItem *), you won't be able to do that directly, as the compiler rightfully has no idea that foo has that signal. So either store it as a Foo *, or you'll need a downcast (qobject_cast if foo may not be a Foo and you need to check the result, static_cast if you're sure it is, but again, if you're sure why not storing with the right type in the first place?)peppe
Thanks, @peppe. I'm not sure why it's a generic QQuickItem either. I replaced it to make it more specific, and your syntax works perfectly. May I suggest that you make your comment into an answer, so that I may accept it (and give you rep in the process)?Phrogz

1 Answers

1
votes

Update the class Bar. Instead of QQuickItem *foo; use Foo *foo;.

class Bar: public QObject {
...
private:
  Foo *foo;
};

//and emit the signal
void Bar::BeforeRender() {
  emit foo->huzzah();
}