Aziuth
Aziuth

Reputation: 3902

QFileDialog: folder name appears twice under windows

What I want to do: Simply have the user select a directory within a Qt UI.

The code so far:

QString dir = QFileDialog::getExistingDirectory(this, "Open directory",
                                                QString::fromStdString(target_dir),
                                                QFileDialog::ShowDirsOnly
                                                | QFileDialog::DontResolveSymlinks);

This works just fine under linux. When I cross compile it for windows, though, what happens is that instead of some_path/directory it returns some_path/directory/directory, that is the name of the selected directory is added twice.

It works fine if I select the folder and happens only when I enter the folder, which should be a thing that the user is able to do.

A reason for this might be that the line edit that in QFileDialog usually contains the file name here contains the folder name and does not clear itself when the folder is entered (which it does under linux).

Now I could write some routine that for a given QString dir checks whether it exists and if not and if the last two folders are identical also tries it without the last folder. This is my makeshift solution, but I don't like it, would prefer if I can solve this within parts of the Qt code.

For compatibility reasons, I have to use Qt 4.8.5.

Found nothing on this issue using search engines.

Does anybody know a way to make this work? After all, this should be a very elemental and simple function of Qt.

Edit: Given the advice from p-a-o-l-o, I tried out removing the flags, had the same problem. Then I also tested doing that without the static function:

QFileDialog dialog;
dialog.setFileMode(QFileDialog::Directory);
QString dir = dialog.getExistingDirectory(this);

Still same problem.

Edit: My makeshift solution, for those who are interested:

QString find_next_valid_folder(const QString& path)
{
    if(QDir(path).exists()) return path;
    return find_next_valid_folder(path.left(path.lastIndexOf("/")));
}

Upvotes: 2

Views: 206

Answers (1)

p-a-o-l-o
p-a-o-l-o

Reputation: 10057

If you don't mind refactoring, you can have a simple class like this:

    #include <QFileDialog>

    class XFileDialog : public QFileDialog
    {
        Q_OBJECT
        QString _current;
    public:
        XFileDialog(QWidget * parent);
        static QString getExistingDirectory(QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), QFileDialog::Options options = QFileDialog::ShowDirsOnly);
    private slots:
        void folderChanged(const QString &);
    };

so you can track QFileDialog signals:

    XFileDialog::XFileDialog(QWidget * parent) : QFileDialog(parent)
    {
        connect(this, SIGNAL(currentChanged(const QString &)), this, SLOT(folderChanged(const QString &)));
    }

in the slot you simply update the _current member:

    void XFileDialog::folderChanged(const QString & s)
    {
        if(s.isEmpty()) return;
        _current = s;
    }

and implement the getExistingDirectory method like this:

    QString XFileDialog::getExistingDirectory(QWidget * parent, const QString & caption, const QString & dir, QFileDialog::Options options)
    {
        XFileDialog dialog(parent);

        dialog.setWindowTitle(caption);
        dialog.setFileMode(QFileDialog::Directory);
        dialog.setOptions(options);
        dialog.setDirectory(dir);
        if(dialog.exec() == QDialog::Accepted)
        {
            return dialog._current;
        }
        return QString();
    }

Notice the static function returns the last known path the user navigated into.

Now you could replace

QString dir = QFileDialog::getExistingDirectory(this, "Open directory",
                                                QString::fromStdString(target_dir),
                                                QFileDialog::ShowDirsOnly
                                                | QFileDialog::DontResolveSymlinks)

with

QString dir = XFileDialog::getExistingDirectory(this, "Open directory",
                                                QString::fromStdString(target_dir),
                                                QFileDialog::ShowDirsOnly
                                                | QFileDialog::DontResolveSymlinks)

Upvotes: 1

Related Questions