C++ – Qt can I connect signals/slots to self in constructor

cqtsignals-slots

EDIT: Not related to signals/slots/connect. Problem was constructor calling constructor.

There might be a better way to do this – I'd be interested in hearing those…

I have MyClass that is derived from a QLabel. I want to pass more data about the derived class back in the signal than what the base signal does. So I made a slot to intercept the customContextMenuRequested signal and emit a revised one that has more data.

When I try to connect up this signal in the constructor, then my slot never gets called. But if I move the Policy and connect lines out to the parent widget(not class hierarchy parent) so they execute after MyClass is fully constructed, then my slot will get called. But I always want that to be connected for this class and it seems like something I would want in it's constructor rather than counting on the parent class to remember to do it.

Is there something I'm doing wrong? Or a better way to add data to a signal?

MyClass::MyClass() : QLabel()
{
    QFont currFont = font();
    currFont.setPointSize(15);
    setFont(currFont);

    setBackgroundRole(QPalette::Mid);

    std::cout << "connecting customContextMenuRequested" << std::endl;
    /** PROBLEM START */
    setContextMenuPolicy(Qt::CustomContextMenu);

    // Is there anything wrong with connecting from "this" to "this" in a constructor?

    QObject::connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
                     this, SLOT(addCellDataToMenuContextRequest(const QPoint&)));
     /* PROBLEM END **/
}


MyClass::MyClass(QString &cellString, int row, int col)
    : QLabel(cellString)
{
    MyClass();
    setRow(row);
    setCol(col);

}

// This one is a slot
void MyClass::addCellDataToMenuContextRequest(const QPoint& pos)
{
        // This doesn't get printed if I connect in my constructor,
        // but it does print if I do the same connect from a parent widget.
    std::cout << "called addCellDataToMenuContextRequest" << std::endl;

    emit customContextMenuRequestedForCell(pos, _row, _col);
}

So I would like the parent widget to just look for customContextMenuRequestedForCell but right now, the parent widget seems to need to be responsible for customContextMenuRequested as well.

Best Answer

Actually, you CAN call (sort of) another constructor if you are using C++11. It's called delegating constructor. But I don't think that will make the problem go away. Your issue seems to be that meta object is not fully constructed when connect() is called. Also, you'll probably need to move to Qt 5 for C++11 to work.

The solution is to delay the connection until the object is fully constructed. You can start a timer with an interval of zero. It will trigger on the next event loop processing which will certainly be after your object is fully constructed.

Then in your timerEvent, make the connection and kill the timer.

EDIT: Didn't see your edit. Looks like you find the solution. Ignore this then. :)

BTW. You didn't call another constructor. You created a temporary MyClass object.

Related Topic