Search code examples
qtqt5qfiledialog

QFileDialog from child window closes the application


I'm new to QT and I'm having issues when calling QFileDialog from a child window. My app is relatively simple. I have one prompt widget that gets user input and then runs show on its parent. This is my main.

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    ParentWidjet w(nullptr);

    ChildWidget input(&w);
    input.show();

    return a.exec();
}

This is the relevant section of the child widget:

ChildWidget::ChildWidget(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::InputPrompt){
    ui->setupUi(this);
    this->setParent(parent);
}
...
void ChildWidget::on_imagesSelect_clicked() {
    inputFilepath = QFileDialog::getExistingDirectory(static_cast<ParentWidget *>(this->parent()), QCoreApplication::translate("main", "Open directory"), "./", QFileDialog::ShowDirsOnly);
    ui->inputPath->setPlainText(inputFilepath);
    std::cout << "y u exit" << std::endl;
}
//Setup and show the parent
void ChildWidget::on_buttonBox_accepted() {
    static_cast<ParentWidjet *>(this->parent())->setup(inputFilepath, outputFilepath);
    static_cast<ParentWidjet *>(this->parent())->show();
}

For some reason when QFileDialog is called, closing it with either OK or Cancel closes both the parent and the child. If I don't use it, but click the OK button of the child, which calls the on_buttonBox_accepted() function, the child closes and the parent widget appears as expected. If I don't pass the parent widget to the child widget in the main, QFileDialog no longer closes the child widget when running. I tried changing the parent of QFileDialog to this or to nullptr but that didn't help.

I think my question is similar to QFileDialog closes window when called

or PyQt5 QFileDialog finishes app when called from child window

But i couldn't extract a solution from them that works for me.


Solution

  • Long story short, the second window is not shown, and there is no action waiting to receive the accept call, so my app just dies. This can be prevented if the quit on last window closed property is disabled. Qt forums suggested a solution, together with a few better design choices. This is what I went with in the end.

    int main(int argc, char *argv[]) {
       QApplication a(argc, argv);
    
       ParentWidget w(nullptr);
    
       ChildWidget input;
       if (  input.exec() == QDialog::accepted)   // exec() blocks execution until ok/cancel. unlike show()
       {
         w.setup(input.inputFilepath, input.outputFilepath); // assuming these are public
         w.show()
       } else 
       {  // user closed or pressed cancelled
         ... what u want to do..
       }
    
        return a.exec();
    }