我有两个课程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();
}
那么如果我想在do_something()
ui
被关闭时(例如按A
),我应该怎么做?似乎Alt-F4
的方式在这里不适用。
非常感谢!
答案 0 :(得分:6)
如果修改A小部件是选项,请向其添加信号并覆盖closeEvent
或hideEvent
并在那里发出新信号。这很强大,您可以完全控制发生的事情。然而,答案的其余部分是出于这样的情况,无论如何,您无法或不愿意混淆A并希望在B类中找到解决方案。
如果您可以在A
上设置Qt::WA_DeleteOnClose
attribute,那么简单的方法就是使B::doSomething()
(注意常见的Qt方法命名约定)成为一个插槽并连接destroyed
signal的A实例。
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
指针,以避免意外引用悬空指针。
如果您不希望A实例在关闭时被删除(如果再次需要则重新创建),那么另一种方法是在A实例上安装事件过滤器,并检测{{3 }}。这有一个潜在的问题,即窗口小部件可以拒绝close事件,并且在关闭之前调用doSomething
。如果这是一个问题,可以通过使用closeEvent
来延迟doSomething
(它必须是插槽或可调用的方法!)调用在close事件结束并且程序返回事件后发生环。然后在doSomething
中检查a
是否真的被隐藏了。检测QEvent::Close
可能效果不错,而不是QEvent::Hide
。
要实现此功能,请覆盖B中的虚拟QMetaObject::invokeMethod
static 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);
}
然后开始使用eventFilter
method监听A
个实例的事件,例如:
B::B(QWidget *parent) : QDialog(parent), ui(new Ui::B)
{
a = new A();
installEventFilter(a);
a.show();
}
答案 1 :(得分:3)
如果你不能使用模态窗口(或对话框),那么你需要继承QWidget(或QDialog或其他QWidget派生类,无论你需要什么)并覆盖{{3} }(对于类 A )并从此处调用父项的方法(我假设 a 将是代码中 this 的子项: a = new A(this); )或编码您自己的信号/插槽。
如果您决定使用模态对话框,代码会变得更简单,请参阅QDialog的QWidget::closeEvent中的示例代码。