c++ - QWidget失去了它的 parent

标签 c++ qt qt5 qwidget qdialog

在我的应用程序中,我有一个 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/

相关文章:

c++ - 代码退出时出现奇怪的访问冲突

c++ - 为什么不能在 C++ 中将 int** 转换为 const int**

c++ - 为什么 clang 在类似问题上进行不同的诊断?

c++ - GaussianBlur 不应该是对称的吗?

qt - Q_DECLARE_METATYPE 根本不起作用

c++ - Qt 动画中最快的代码更改像素

qt - QAbstractItemView 向模型询问无效索引

c++ - 错误的输出 - Ramanujan 对阶乘和 C++ 的近似

c++ - QT 5 给设计器添加继承自QGraphicsView的自定义widget

c++ - 在 Windows 中调试 QT 5.8 和打开 QFileDialog 时,gdborig.exe 随机崩溃