1

I'm asking if there is a way to use signals in a class which inherits from QObject like this:

mysuperclass.cpp

#include "mysuperclass.h"

MySuperclass::MySuperclass(quint16 port, QObject *parent) :
  QObject(parent), port(port)
{
  this->connected = false;
}

mysuperclass.h

#include <QAbstractSocket>

class MySuperclass: public QObject
{
  Q_OBJECT
public:
  explicit MySuperclass(quint16 port = 0, QObject *parent = 0);

signals:
   //there is nothing here
public slots:
  virtual void newValue(){qDebug() << "newValue";}
  virtual void connectionEstablished(){qDebug() << "connectionEstablished";}
  virtual void disconnected(){qDebug() << "disconnected";}
protected:
  QAbstractSocket* networkSocket;
  quint16 port;
  bool connected;
};

mysubclass.cpp

#include <QTcpSocket>
#include <QHostAddress>

MySubClass::MySubClass(quint16 ServerPort, QObject *parent) : 
  MySuperClass(ServerPort, parent) 
{
  this->networkSocket = new QTcpSocket(this);
  ...
  connect(this->networkSocket, SIGNAL(connected()),this,
    SLOT(connectionEstablished()));
  connect(this->networkSocket, SIGNAL(disconnected()),this,
    SLOT(disconnected()));
  connect(this->networkSocket, SIGNAL(readyRead()),this, SLOT(newValue()));
}

mysubclass.h

#include <QObject>
#include "mysuperclass.h"

class MySubClass: public MySuperClass
{
 public:
   MySubClass(quint16 ServerPort, QObject* parent=0);

 public slots:
   void newValue();
   void connectionEstablished();
   void disconnected();
};
cbuchart
  • 10,847
  • 9
  • 53
  • 93
kamal
  • 49
  • 1
  • 8

1 Answers1

6

You must include the Q_OBJECT macro in the derived class too (but don't derive from QObject again). The macro is only mandatory if the derived class declares signals or slots. For emitting parent's signals or connecting with parent's slots it is not necessary (it also means that it is not necessary to re-define already existing signals or slots).

From Qt's documentation:

The Q_OBJECT macro must appear in the private section of a class definition that declares its own signals and slots or that uses other services provided by Qt's meta-object system.

Example

class MySubClass : public MySuperClass {
  Q_OBJECT

  public:
    MySubClass(quint16 ServerPort, QObject* parent=0);

  public slots:
    void newValue();
    void connectionEstablished();
    void disconnected();
};

On the other hand, if you want to connect to a slot in the parent class but implement it in a derived one, then you must make it virtual:

class MySuperclass : public QObject {
  Q_OBJECT
  // ...
public slots:
  virtual void newValue(); // can be virtual pure also
};

class MySubClass : public MySuperClass {
public:
  virtual void newValue() override; // overrides parent's
}

Note that there is no need to use the Q_OBJECT macro nor to use the slot: label in the derived class. Slots are normal methods after all. Of course, you have to use it if you add new slots or signals.

cbuchart
  • 10,847
  • 9
  • 53
  • 93
  • Sorry! but what you suggeste doesn't work :/ here is what i get: `warning: C4584: 'MySubClass': the basic class 'QObject' is already a basic class of 'MySuperClass'` and `Error: C2385: ambiguous access to 'connect'` – kamal Apr 21 '17 at 11:21
  • May you please post a more complete code (update your question) of both classes as well as the `connect` line that is failing to compile? – cbuchart Apr 21 '17 at 11:23
  • Mmm... please, update your question with that code correctly formatted, it's quite difficult to read it in comments. Also, publish the code of the super and derived classes you mentioned. – cbuchart Apr 21 '17 at 11:27
  • sorry for the illegible code but i don't have another way :/ – kamal Apr 21 '17 at 11:29
  • In the meanwhile, please take a look at the updated answer to see if the new additions regarding inheriting from `QObject` helps you. – cbuchart Apr 21 '17 at 11:46
  • Is there any slot in `MySuperclass` called `connect`? – cbuchart Apr 21 '17 at 11:55
  • not realy a `connect` slot but you can look at again my code i updated it – kamal Apr 21 '17 at 12:02
  • I've successfully compiled your example afer two changes: add the `Q_OBJECT` macro to `MySubClass` (or remove the `public slots:` line), and you have a typo: `MySuperclass` in some places and `MySuperClass` in other ones... may be you have two clases and it is confusing? Nevertheless, after those changes it compiled correctly. Anything else you are missing to publish? Is the failing line included (the one with the ambiguous `connect`)? – cbuchart Apr 21 '17 at 12:12
  • i have errors again: =>`MySubClass.obj:-1: error: LNK2001: Unresolved external symbol "public: virtual struct QMetaObject const * __thiscall MySubClass::metaObject(void)const " (?metaObject@MySubClass@@UBEPBUQMetaObject@@XZ)` =>`MySubClass.obj:-1: error: LNK2001: Unresolved external symbol "public: virtual void * __thiscall MySubClass::qt_metacast(char const *)" (?qt_metacast@MySubClass@@UAEPAXPBD@Z)` =>`MySubClass.obj:-1: error: LNK2001: Unresolved external symbol "public: virtual int __thiscall MySubClass::qt_metacall(enum QMetaObject::Call,int,void * *)"` – kamal Apr 21 '17 at 12:29
  • @kamal, I think the problem is expanding out of the original question. Have you tried with a [mcve] and from there start expanding your code until your final project? The last error is usually related to missing moc files. Take a look at [the documentation](http://doc.qt.io/qt-5.8/moc.html). What compiler/IDE are you using? qmake and Visual Studio Qt plugins takes those steps for you. – cbuchart Apr 21 '17 at 13:32
  • Another option, but less probable given the samples you've published, is that `MySubClass` is _declared_ in a .cpp file instead of a .h one. – cbuchart Apr 21 '17 at 13:33
  • The core thing with the aforementioned error is that the linker is not able to find the definitions of methods created when the `Q_OBJECT` macro was included. May be you have to update your project (running qmake if used) or recompiling everything? There can be many causes. – cbuchart Apr 21 '17 at 13:34
  • After a short googling, found [this answer](http://stackoverflow.com/a/14172787/1485885). Take a look at it. – cbuchart Apr 21 '17 at 13:39