简体   繁体   English

在QT中,从closeEvent函数发出信号是否安全?

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

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? 我冒险崩溃导致对象obj在发出信号之后和cleanUp函数返回之前被销毁了吗?

Thanks a lot. 非常感谢。

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 . 它是,因为信号/插槽系统的工作方式类似于函数调用(添加了“连接”机制),如Qt文档中有关信号和插槽的说明

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. 因此, closeEvent函数中的下一行代码,就在信号之后,将在连接到此信号的所有插槽返回后执行。

Thus, in your case, the A object will still be there and valid. 因此,在您的情况下,A对象仍然存在且有效。 Note that closing a widget doesn't necessarily delete it (as noted by vahancho in the comments). 请注意,关闭窗口小部件不一定会删除它(如注释中的vahancho所述)。

EDIT : In fact, it depends if you manipulate A through a pointer in cleanup . 编辑事实上,这取决于你是否通过cleanup的指针操纵A. 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 ). 如果B没有存储指向A的指针,无论如何都会没问题(因为无论如何都会发出信号,将调用插槽,如果插槽内没有访问A ,那就没问题了所有, 无论指定或假设的连接类型如何 )。 If cleanup somehow accesses A through a pointer, then read the following: 如果cleanup以某种方式通过指针访问A ,那么请阅读以下内容:

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. 正如所指出的那样,我确实应该已经确定只有在你使用Qt::DirectConnection模式进行此连接时才会出现这种情况。 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, ie signal from a thread to a slot that'd run in another thread) 实际上,这种模式产生了我描述的行为,并且被假定( connect函数的默认参数是Qt::AutoConnection ,它根据上下文自动选择,即从线程到另一个线程中运行的槽的信号)

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. 如果您使用Qt::QueuedConnection或者Qt::AutoConnection假设它,那么您确实可能有未定义的行为,因为对插槽的调用将排队到接收器线程,并且只有在控制返回到该线程的事件循环时才会执行。 If this happens after A has been actually destroyed, 如果在A被实际销毁之后发生这种情况,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM