gpt4 book ai didi

c++ - QWidget失去了它的 parent

转载 作者:行者123 更新时间:2023-11-28 05:30:36 25 4
gpt4 key购买 nike

在我的应用程序中,我有一个 QDialog,它本身包含一个复杂的、QWidget 派生的 GUI 元素。 QDialog 是模态的,用 exec() 打开,嵌入式 GUI 元素处理所有用户交互。

所以只有这个子QWidget知道什么时候可以关闭QDialog,这是这样完成的:

QDialog* parent=qobject_cast<QDialog*>(parentWidget());
if (parent) parent->close();

这是必要的,因为必须关闭 QDialog 而不仅仅是 QWidget

现在,一位用户报告了一种情况,其中 QDialog::exec() 已返回,但对话框(或仅 GUI 元素?)仍然可见。从日志文件中,我可以看到 QDialog::exec() 确实返回了并且执行了此调用之后的代码。

所以我目前的假设是:GUI 元素失去了它的父元素,所以上面显示的 close() 调用没有被调用,因为“parent”为空。

知道这是怎么发生的吗? QWidget 的父级是否可以通过常规方式消失?

最佳答案

一般来说,使用QDialog::exec重新进入事件循环会造成麻烦,因为突然所有在主线程中运行的代码都必须是可重入的。您很可能正面临由此带来的影响。不要重新进入事件循环,你会没事的,否则问题将变得可重现。

如果您需要对接受或拒绝的对话使用react,请将代码连接到相关插槽。 IE。改变这个:

void do() {
MyDialog dialog{this};
auto rc = dialog.exec();
qDebug() << "dialog returned" << rc;
}

对此:

class Foo : public QWidget {
MyDialog dialog{this};
...
Foo() {
connect(&dialog, &QDialog::done, this, &Foo::dialogDone);
}
void do() {
dialog.show();
}
void dialogDone(int rc) {
qDebug() << "dialog returned" << rc;
}
};

或者,如果你想延迟初始化对话框:

class Foo : public QWidget {
MyDialog * m_dialog = nullptr;
MyDialog * dialog() {
if (! m_dialog) {
m_dialog = new MyDialog{this};
connect(m_dialog, &QDialog::done, this, &Foo::dialogDone);
}
return m_dialog;
}
...
void do() {
dialog()->show();
}
void dialogDone(int rc) {
qDebug() << "dialog returned" << rc;
}
};

子部件试图干预父部件是一种可怕的反模式。 小部件有父级的知识不应该泄漏到小部件中,它应该被本地化到父级。因此,子小部件应该发出一个信号,表明例如数据被接受。创建对话框时,将此信号连接到对话框的 accept()close() 插槽:

class MyWidget : public QWidget {
Q_OBJECT
public:
Q_SIGNAL void isDone();
...
};

class MyDialog : public QDialog {
QGridLayout layout{this};
MyWidget widget;
public:
MyDialog() {
layout.addWidget(&widget, 0, 0);
connect(&widget, &MyWidget::isDone, this, &QDialog::accepted);
}
};

关于c++ - QWidget失去了它的 parent ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39636406/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com