Kvass
Kvass

Reputation: 8434

Close QFileDialog only when click "open"

Whenever I select a file in my QFileDialog the accepted signal is fired and the window closes. I want to keep the window open so I can select multiple files and then capture the signal fired when "open" is clicked.

QFileDialog* myDialog = new QFileDialog(this);
myDialog->setFileMode(QFileDialog::ExistingFiles);
myDialog->setVisible(true);

What signals should I be connecting here to achieve this effect?

Upvotes: 0

Views: 2186

Answers (4)

Rafe
Rafe

Reputation: 2065

I don't think anyone has understood the question (or it could be just me looking for my own solution)...

I had the same issue. As soon as I clicked a file the dialog would close. I couldn't ever select a file and then click "Open" because the dialog instantly closed as soon as I single clicked a file.

related: qtcentre.org/threads/48782-QFileDialog-single-click-only

It turns out it was my linux os settings (under mouse). File opening was set to single-click. I still feel like something external might have toggled this but that is just speculation. It appears Qt was going the right thing. Check another application, like kate on KDE and see if it has the same behavior. That is what clued me in to the source of my issue.

Upvotes: 0

Jablonski
Jablonski

Reputation: 18504

Whenever I select a file in my QFileDialog the accepted signal is fired and the window closes. I want to keep the window open so I can select multiple files

All other answers is just solution for selection many files one time and CLOSE window after Open button pressing. Get my solution, it is not very simple because it required lot of work:

I used lamda expressions and new signals and slots syntax in my answer, but you can use old syntax or add

CONFIG += c++11

to the .pro file and use lambdas.

Subclass QFileDialog:

Header:

#ifndef CUSTOMFILEDIALOG_H
#define CUSTOMFILEDIALOG_H

#include <QFileDialog>
#include <QDebug>

class CustomFileDialog : public QFileDialog
{
    Q_OBJECT
public:
    explicit CustomFileDialog(QWidget *parent = 0);

    void setDefaultGeo(QRect);

signals:
    void newPathAvailable(QStringList list); 
public slots:

private:
    bool openClicked;
    QRect geo;

};

#endif // CUSTOMFILEDIALOG_H

When you click open, you hide your dialog, not close! Cpp:

#include "customfiledialog.h"

CustomFileDialog::CustomFileDialog(QWidget *parent) :
    QFileDialog(parent)
{
    openClicked = false;
    connect(this,&QFileDialog::accepted,[=]() {
        openClicked = true;
        qDebug() << openClicked;
        this->setGeometry(geo);
        this->show();
        emit newPathAvailable(this->selectedFiles());
    });
}

void CustomFileDialog::setDefaultGeo(QRect rect)
{
    geo = rect;
}

Usage:

CustomFileDialog *dialog = new CustomFileDialog;
QStringList fileNames;
dialog->setFileMode(QFileDialog::ExistingFiles);
dialog->show();
dialog->setDefaultGeo(dialog->geometry());
connect(dialog,&CustomFileDialog::newPathAvailable,[=](QStringList path) {
    qDebug() << path;
});

Why do you need setDefaultGeo? Without this method, your window will move after Open pressing.

What we get?

I open filedialog and select two files:

enter image description here

I clicked Open, but window didn't close! You can choose new files again and again!

enter image description here

One more file and so on:

enter image description here

Window will closed only when user press Close button, but you will have all path which user choose.

As you said:

I want to keep the window open so I can select multiple files

You get this.

Upvotes: 0

Nithish
Nithish

Reputation: 1640

Your code looks fine to me. I believe you are double clicking on the file inside the dialog instead of holding on the Ctrl and single clicking on all the files you need.

You can optionally use an event filter and ignore the double click event.

Once you click on Open, you can get a list of all the file paths in the QStringList given by QFileDialog::selectedFiles(). Also it's better to use a stack variable here and use exec method to launch it as pointed out by BaCaRoZzo.

QFileDialog myDialog(this);
myDialog.setFileMode(QFileDialog::ExistingFiles);
if(myDialog.exec())
{
    qDebug() << myDialog.selectedFiles();
}

Upvotes: 2

BaCaRoZzo
BaCaRoZzo

Reputation: 7692

The QFileDialog::ExistingFiles should guarantee that multiple files can be selected. Given that, you can connect to the signal:

void QFileDialog::filesSelected(const QStringList & selected)

Directly from the documentation:

When the selection changes for local operations and the dialog is accepted, this signal is emitted with the (possibly empty) list of selected files.

However, if you are only interested in collecting such files, you can totally avoid signal-slot and write (taken again from the documentation):

QStringList fileNames;
if (dialog.exec())
    fileNames = dialog.selectedFiles();

Note that in this case dialog object has been created on the stack (which is the common approach for such objects).

Upvotes: 6

Related Questions