我有两个类 A
和 B
,这是 B.h
中的一个片段:
#include "A.h"
class B : public QDialog
{
Q_OBJECT
public:
void do_something();
private:
A *a;
}
在 B.cpp
中:
B::B(QWidget *parent) :
QDialog(parent),
ui(new Ui::B)
{
a = new A();
a.show();
}
那么当 A
的 ui
关闭时(按 Alt-F4
,例如)? signal-slot
的方式似乎不能在这里应用。
非常感谢!
最佳答案
修改A类关闭时发出信号
如果修改 A 小部件是选项,请向其添加信号并覆盖 closeEvent
或 hideEvent
并在那里发出新信号。这是稳健的,您可以完全控制发生的事情。然而,其余的答案是针对这样的情况,无论出于何种原因,您不能或不愿意与 A 打交道并希望在 B 类中找到解决方案。
使用Qt信号删除QObject
如果可以设置Qt::WA_DeleteOnClose
attribute在 A
上,简单的方法是使 B::doSomething()
(注意常见的 Qt 方法命名约定)成为插槽并连接 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();
}
当然,即使您显式地删除 a;
而不是自动使用该属性,这仍然有效。
注意:在这种情况下,当对象可能随时被删除时,您应该真正使用 QPointer
对于 a
指针,避免意外引用悬空指针。
使用Qt事件过滤器
如果您不想在关闭时删除 A 实例(如果再次需要则重新创建),那么另一种方法是在 A 实例上安装事件过滤器,并检测 closeEvent
.这有一个潜在的问题,即小部件可以拒绝关闭事件,并且在任何情况下 doSomething
都会在关闭之前被调用。如果这是一个问题,可以使用 QMetaObject::invokeMethod
static method 解决。延迟 doSomething
(它必须是插槽或可调用方法!)调用在关闭事件结束并且程序返回到事件循环后发生。然后在 doSomething
中检查 a
是否真的被隐藏了。代替 QEvent::Close
,检测 QEvent::Hide
也可能工作良好。
要实现这一点,请覆盖虚拟 eventFilter
method在 B 中,是这样的:
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();
}
关于c++ - Qt - 当另一个对话框关闭时如何做我想做的事?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20353112/