c++ - Qt - 当另一个对话框关闭时如何做我想做的事?

标签 c++ qt user-interface qt5

我有两个类 AB,这是 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();
}

那么当 Aui 关闭时(按 Alt-F4,例如)? signal-slot 的方式似乎不能在这里应用。
非常感谢!

最佳答案

修改A类关闭时发出信号

如果修改 A 小部件是选项,请向其添加信号并覆盖 closeEventhideEvent 并在那里发出新信号。这是稳健的,您可以完全控制发生的事情。然而,其余的答案是针对这样的情况,无论出于何种原因,您不能或不愿意与 A 打交道并希望在 B 类中找到解决方案。

使用Qt信号删除QObject

如果可以设置Qt::WA_DeleteOnClose attributeA 上,简单的方法是使 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/

相关文章:

c++ - 连接 vector 的 Constexpr 函数

qt - 我在哪里可以找到 QMake 的源代码库?

c++ - 无法理解如何使用 drawText for qpainter 旋转文本

c++ - 库中的 Qt GUI?

c++ - 使用 Microsoft 的可扩展存储引擎创建一个唯一的、自动分配的变量

c++ - 我可以在 MacOS X 10.11 上让 gcc/g++ 指向 ACTUAL gcc/g++ 吗?

c++ - 使用 Visual Studio 在 Opengl 1 中创建纹理动画的最佳方法是什么?

python - Qt ShortcutOverride 默认 Action

ruby - 如何安装 Ruby Shoes?

c# - 如何在 Silverlight C# for WP7 中使用 NavigationService 作为同步回调的结果?