【问题标题】:Qt5 QFileDialog closes parent dialog as wellQt5 QFileDialog 也关闭父对话框
【发布时间】:2021-10-15 03:13:46
【问题描述】:

我有一个带有“保存”按钮的自定义 QDialog,它应该使用 QFileDialog 提示用户并将 Table Widget 的内容保存到文件中,但保持对话框打开。

这是打开对话框并保存数据的函数:

bool ResultsDialog::saveData()
{
    QString outfile = QFileDialog::getSaveFileName(this, tr("Save results"), tr(""), tr("CSV Files (*.csv)") );
    if (outfile.isNull() || outfile.isEmpty() )
        return false;
    if (!CSVIO::write_to_csv(*ui->tableWidget, outfile) )
    {
        QMessageBox::critical(this, "Failed to save...", QString("Could not save file: %1").arg(outfile) );
        return false;
    }
    return true;
}

这是保存按钮槽的代码:

void ResultsDialog::on_saveButton_clicked()
{
    if (saveData() )
    {
        saved = true;
    }
}

编辑:这是创建和打开 ResultsDialog 的代码:

void MainWindow::displayResults()
{
    ResultsDialog *resultsDialog = new ResultsDialog(this);
    resultsDialog->setWindowTitle(windowTitle() );
    resultsDialog->setWindowIcon(windowIcon() );

    connect(resultsDialog, &ResultsDialog::finished, this, &MainWindow::close);

    resultsDialog->fill(playlistTable, notes);
    resultsDialog->setModal(true);
    resultsDialog->open();
    this->hide();
}

问题是,QFileDialog一关闭,我的QDialog也随之关闭,控制台打印如下信息:

qt.qpa.xcb:QXcbConnection:XCB 错误:3(BadWindow),序列:13049, 资源 id:25205189,主要代码:40(TranslateCoords),次要代码:0
11:59:01:/home/user1/workspace/build-App-Desktop-Debug/App 退出 代码为 0

请注意,我的自定义对话框的父级 MainWindow 已隐藏。当它不被隐藏时,这个问题就会消失,但这不是一个选项,因为我希望 MainWindow 被隐藏。

我在 Debian Bullseye 上使用 Qt 5.15。

【问题讨论】:

  • 只是检查我是否理解得很好:所以如果你的 MainWindow 没有隐藏,那么在 QFileDialog 关闭后你的 ResultsDialog 不会自动关闭?
  • 没错。我正在添加打开 ResultsDialog 的代码。

标签: c++ linux qt dialog qt5


【解决方案1】:

您正在将 MainWindow 的终止连接到在 ResultsDialog 仍在处理时发出的信号。 ResultsDialog 将 MainWindow 作为其父级,因此父级(及其子级!!)在子级仍在运行时被销毁。这种结构不会产生任何好处。

编辑:您看到的错误消息不是问题的根源,而只是一个窗口突然关闭的指示。这正是你所描述的。

编辑 2:请参阅评论部分以了解解决方法(将 0 作为父级传递给对话框)并猜测解决方法为何有效。

【讨论】:

  • 这可能是也可能不是问题,但这不是这里的问题。我对这个结构没有任何其他问题。当 ResultsDialog 关闭时,应用程序应该退出。 QFileDialog 正在做的事情是触发 ResultsDialog 在它应该关闭之前关闭,我无法找出它是什么 - 这就是问题所在。
  • 我错过了故意关闭和神奇关闭的重点。这里发生了一些模糊的事情:您可以使用 exex() 而不是 open() 打开 ResultsDialog 以使其成为正确的应用程序模式对话框(您可能必须为此反转 hide 和 exec 调用)?如果打破父层次结构并在 ResultsDialog 的构造函数和 getSaveFileName 中传递 0 会发生什么?
  • 我可以发誓我尝试将 0 作为 ResultsDialog 的父级传递,但它现在似乎已经成功了。至少在 Linux 上——因为该应用程序也需要在 Mac 和 Windows 上运行,所以我也会对它们进行测试。将 0 传递给 getSaveFileName 没有任何效果。在 exec() 和 open() 之间切换也没有区别。
  • 我猜,一些内部尝试访问 MainWindow 工具栏的大小,隐藏时可能会给出 0,并且某些元素试图在一个部门中使用这个 0。传递 0 会破坏隐藏栏的访问链。
  • 很高兴知道...当 QFileDialog 被取消时,它会触发该功能并且消息框使应用程序保持活动状态 - 尽管即使单击了Go Back 按钮,当消息框关闭时应用程序仍然会死掉。我可以确认此解决方法适用于 macOS 和 Windows,因此我会接受您的回答。
猜你喜欢
  • 2012-04-05
  • 1970-01-01
  • 2019-04-06
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多