Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why QFileDialog::selectFile doesn't work?

Tags:

c++

qt

I am using Qt 5.12 and trying to write test (using QTest) for opening of project stored in some xml format.

In test I use QTimer::singleShot to wait QFileDialog to appear as proposed in QT close window by QTest in locked thread.

The problem is that QFileDialog::selectFile doesn't select anything. This means that OK button is not active, so I can't click on it in my test.

I assume in the following example that full path to file is /tmp/project.xml. Notice that QFileDialog::setDirectory works great: when the following example starts, you are in /tmp dir instead of /.

#include <QApplication>

#include <QFileDialog>
#include <QTimer>

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

    QTimer::singleShot(300, []() {
        QWidget* window = nullptr;
        while (!window) {
            window = qApp->activeModalWidget();
        }
        QFileDialog* fd = qobject_cast<QFileDialog*>(window);

        fd->setDirectory("/tmp");
        fd->selectFile("project.xml");
    });

    QString path = QFileDialog::getOpenFileName(nullptr, "Open Project",
                                                "/", QString(),
                                                nullptr, QFileDialog::DontUseNativeDialog);
}

1 Answers

The function selectFile didn't work because of the file name text box (lineEdit) is focused. This behavior comes from the implementation of QFileDialog::selectFile() :

void QFileDialog::selectFile(const QString &filename)
{
    // ... function body

    //Put the filename into the lineEdit when :
    //1. The dialog is not visible or
    //2. The lineEdit is not focused.

    if (!isVisible() || !d->lineEdit()->hasFocus())
        d->lineEdit()->setText(index.isValid() ? index.data().toString() : fileFromPath(d->rootPath(), filename));
}

To make the program works, there are two ways :

  1. Put the file name directly in the text box
  2. Give the focus away then call selectFile

       fd->setDirectory("/tmp");
    
       QLineEdit * lineEdit = qobject_cast<QLineEdit*>(fd->focusWidget());
    
        if( lineEdit ){
    
            //Method 1
            lineEdit->setText("project.xml");
    
            //Method 2
            lineEdit->nextInFocusChain()->setFocus();
            fd->selectFile("project.xml");
    
        }else { //no lineEdit focus found
    
            fd->selectFile("project.xml");
        }
    
like image 102
tunglt Avatar answered Dec 19 '25 15:12

tunglt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!