Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In QT is it safe to emit a signal from a closeEvent function?

Tags:

c++

qt

Please, consider the following code

class A : public QWidget
{
    signals:
       void readyToBeClosed();
    protected:
       void closeEvent(QCloseEvent* e)
       {
           QWidget::closeEvent(e);
           emit readyToBeClosed();
       }
}

class B: public QWidget
{
public:
   B(A* obj)
   {
       connect(obj,SIGNAL(readyToBeCLosed()),this,SLOT(cleanUp());
   }

private slots:
   void cleanUp()
   {
        //DO SOMETHING
   }
}

Is it safe? May I risk to crash cause the object obj is destroyed after the emit signal and before the cleanUp function returned?

Thanks a lot.

like image 235
Guido Ranzuglia Avatar asked Dec 31 '25 20:12

Guido Ranzuglia


1 Answers

It is, because the signal/slot system works like function calls (with the addition of the "connection" mechanism), as specified in the Qt Documentation about Signals and Slots.

When you emit a signal, all slots connected to it are called, and once they've all returned, control returns to the code that emitted the signal. So, the next line of code in your closeEvent function, just after the signal, will execute after all slots connected to this signal have returned.

Thus, in your case, the A object will still be there and valid. Note that closing a widget doesn't necessarily delete it (as noted by vahancho in the comments).

EDIT: In fact, it depends if you manipulate A through a pointer in cleanup. If B doesn't store a pointer to A, it will be fine no matter what (because the signal will be emitted anyway, the slot will be called, and if A isn't accessed inside the slot, there'll be no problem at all, whatever the connection type that has been specified or assumed). If cleanup somehow accesses A through a pointer, then read the following:

As pointed out, I should indeed have precised that this is the case only if you're using a Qt::DirectConnection mode for this connection. Indeed, this mode yields the behavior I described, and is assumed (the default parameter for the connect function is Qt::AutoConnection, which automatically choose based on the context, i.e. signal from a thread to a slot that'd run in another thread)

If you use Qt::QueuedConnection or that the Qt::AutoConnection assumes it, then you could indeed have undefined behavior because the call to the slot will be queued to the receiver thread and will only execute once control returns to this thread's event loop. If this happens after A has been actually destroyed,

like image 99
JBL Avatar answered Jan 03 '26 09:01

JBL



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!