修改类 A 以在关闭时发出信号
如果修改 A 小部件是选项,请向其添加信号并覆盖 closeEvent 或 hideEvent 并在那里发出新信号。这是强大的,您可以完全控制发生的事情。但是,其余的答案是针对无论出于何种原因,您无法或不愿意与 A 混淆并希望在 B 类中找到解决方案的情况。
使用 Qt 信号进行 QObject 删除
如果您可以在A 上设置Qt::WA_DeleteOnClose attribute,那么简单的方法是使B::doSomething()(注意常见的Qt 方法命名约定)成为一个插槽并将A 实例的destroyed signal 连接到该插槽。
B::B(QWidget *parent) : QDialog(parent), ui(new Ui::B)
{
a = new A();
a->setAttribute(Qt::WA_DeleteOnClose);
connect(a, SIGNAL(destroyed(QObject*)), SLOT(doSomething()));
a.show();
}
当然,即使您明确地delete a;,这也有效,而不是自动使用该属性。
注意:在这种情况下,当对象随时可能被删除时,您应该真正使用QPointer 作为a 指针,以避免意外引用悬空指针。
使用 Qt 事件过滤器
如果您不想在A实例关闭时将其删除(如果再次需要则重新创建),那么另一种方法是在A实例上安装事件过滤器,并检测closeEvent .这有一个潜在的问题,小部件可以拒绝关闭事件,并且无论如何doSomething 在关闭之前被调用。如果这是一个问题,可以通过使用QMetaObject::invokeMethod static method 来延迟doSomething(它必须是槽或可调用的方法!)调用在关闭事件结束并且程序返回事件循环后发生。然后在doSomething 中检查a 是否真的被隐藏了。代替QEvent::Close,检测QEvent::Hide 也可能效果很好。
要实现这一点,请覆盖 B 中的虚拟 eventFilter method,如下所示:
bool B::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::Close) { //or QEvent::Hide maybe
qDebug("QCloseEvent!");
// check that object is indeed this->a before calling this->doSomething()
if (qobject_cast<QObject *>(a) == obj) {
doSomething();
//alternative, make doSomething to be called later from event loop:
//QMetaObject::invokeMethod(this, "doSomething", Qt::QueuedConnection);
} else {
qDebug("...but the object is not what is expected, a bug?");
}
// do not block the event, just detect it
}
// proceed with standard event processing
return QObject::eventFilter(obj, event);
}
然后使用installEventFilter 开始监听A 实例的事件,类似于:
B::B(QWidget *parent) : QDialog(parent), ui(new Ui::B)
{
a = new A();
installEventFilter(a);
a.show();
}