将信号用于继承自QObject的类

时间:2017-04-21 09:46:59

标签: c++ qt inheritance signals-slots

我问是否有办法在signals这样继承的类中使用QObject

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();
};

1 个答案:

答案 0 :(得分:6)

您必须在派生类中包含Q_OBJECT宏(但不要再次从QObject派生)。只有派生类声明信号或槽时,宏才是必需的。为了发出父信号或与父信令连接,没有必要(这也意味着没有必要重新定义已经存在的信号或时隙)。

来自Qt's documentation

  

Q_OBJECT宏必须出现在类定义的私有部分中,该部分定义声明自己的信号和插槽,或使用Qt的元对象系统提供的其他服务。

示例

class MySubClass : public MySuperClass {
  Q_OBJECT

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

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

另一方面,如果要连接到父类中的插槽但是在派生类中实现它,则必须将其设置为虚拟:

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
}

请注意,不需要使用Q_OBJECT宏,也不需要在派生类中使用slot:标签。毕竟插槽是正常的方法。当然,如果添加新的插槽或信号,则必须使用它。