Search code examples
c++qtqtcoreqobjectqt-signals

Error with QObject::connect()


I am trying to run QTimer and have it warn me when timeouting. To do so, I use slot and signal to link the two.

The guy.h:

#ifndef GUY_H
#define GUY_H

#include <QGraphicsItem>
#include <QTimer>
#include <QObject>

class Guy : public QGraphicsItem
{
public:
    Guy(int x, int y);

    void timerStart();

public slots:
    void onTimeOutTimer();

    [...]

    QTimer *timer;
}

#endif // GUY_H

The guy.cpp:

#include "guy.h"

#include <QTimer>
#include <QObject>

#include <stdio.h>
#include <iostream>

Guy::Guy(int x, int y)
{
    timer = new QTimer();
}

void Guy::timerStart()
{
    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(onTimeOutTimer()));
    this->timer->setInterval(1000);
    this->timer->start();
    std::cout << "starting timer" << std::endl;
}

void Guy::onTimeOutTimer()
{
    std::cout << "check" << std::endl;
}

But as an ouput, I get this error:

No matching function for call to 'QObject::connect(QTimer*&, const char*, Guy* const, const char*)'

As I undertsand it is that QTimer is no QObject required as first input of the function connect(), but the documentation specifies QTimer inherits from QObject. I have no clue here.


Solution

  • You will need to inherit from QObject, too, to get this working as signals and slots are availabl for QObjects. QGraphicsItem does not inherit QObject, not even indirectly.

    Not only that, you will also need to add the Q_OBJECT macro as follows:

    class Guy : public QObject, public QGraphicsItem
    {
        Q_OBJECT
        ...
    }
    

    or even better because QGraphicsObject inherits QObject and QGraphicsItem.

    ...
    #include <QGraphicsObject>
    ...
    
    class Guy : public QGraphicsQObject
    {
        Q_OBJECT
        ...
    }
    

    Also, if you make this change, I suggest to change the QObject::connect to connect as you do not need to indicate the QObject:: scope then.

    On a side note, including stdio.h does not seem to make sense here.

    Furthermore, allocating the QTimer instance on the heap looks like wasteful to me. It is not only leaking the memory, but also adds additional complexity. Even if you allocate it on the heap, you should pass this as the parent and use the initializer list or C++11 style initialization. Also, if you allocate it on the heap, you could use forward declaration in the header.

    If the slot is not used outside the class, you should also make that private.

    It is probably also a bad idea to make the timer member public. Hopefully you do not do that.