Search code examples
c++qt4shared-ptrqt-signals

Object::connect: No such signal when obj is returned as shared_ptr


Using Qt's signal & slot, I get error:

Object::connect: No such signal FvOverlayPolygon::mouseHoveredOnElemSig(rf::AbstractFvOverlay*)

My other connects work fine and I've checked everything I can think of (refered to 20 ways to debug Qt signals and slots too). Because I personally for the first time use shared_ptr for Qt for this sample, I suspect there might be something wrong in how I use shared_ptr. I really appreciate your opinions.


concreteFvOverlay.cpp

#include "rf_common/abstractFvOverlay.h"

void FvScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
  rf::AbstractFvOverlay::Ptr item_overlay;
  item_overlay = this->createOverlay(myItemMenu, &pixmap_overlay); // this inherits Class A

  bool con1 = connect(item_overlay.get(), SIGNAL(mouseHoveredOnElemSig(rf::AbstractFvOverlay*)), this, SLOT(mouseHoveredOnElem(rf::AbstractFvOverlay*)));
  }
}

This overlay is instantiated in this: abstractFvOverlay.cpp

boost::shared_ptr<rf::AbstractFvOverlay> FvPolygonScene::createOverlay(QMenu *menu, QPixmap *pixmap_overlay)
{
  return boost::shared_ptr<rf::AbstractFvOverlay>(new FvOverlayPolygon(menu, *pixmap_overlay));
}

overlay.h

#include <QGraphicsItem>
#include <boost/shared_ptr.hpp>

class AbstractFvOverlay : public QObject, public QGraphicsItem
{
Q_OBJECT

public:
  AbstractFvOverlay(QMenu *contextMenu, QGraphicsItem *parent, QGraphicsScene *scene);
  virtual ~AbstractFvOverlay();
  typedef boost::shared_ptr<AbstractFvOverlay> Ptr;

signals:
  void mouseHoveredOnElemSig(AbstractFvOverlay *i);

For your interest, the reason I use shared_ptr here is I want to do interface-based programming (not sure if this is an official way to call this style but what I mean is defining behavior in abstract classes and only for some behaviors I describe them in concrete classes, which Java allow).


Solution

  • You must use full scope names of types in signal declaration even if you're in same scope. Replace signal void mouseHoveredOnElemSig(AbstractFvOverlay *i); with void mouseHoveredOnElemSig(rf::AbstractFvOverlay *i); or use AbstractFvOverlay without scope in your connect.