Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QFileDialog that accepts a single file or a single directory

Is it possible to show a QFileDialog where the user can select a file or a directory, either one?

QFileDialog::getOpenFileName() accepts only files, while QFileDialog::getExistingDirectory() is directories-only, but I need to show a file dialog that can accept both a file or a directory (it makes sense for my program). QFileDialog::​Options didn't have anything promising.

like image 683
sashoalm Avatar asked Dec 17 '14 07:12

sashoalm


People also ask

What is QFileDialog?

The QFileDialog class enables a user to traverse the file system in order to select one or many files or a directory. The easiest way to create a QFileDialog is to use the static functions.

What does QFileDialog return?

If you want to do this, you should create the dialog yourself using one of the QFileDialog constructors. This is a convenience static function that will return an existing directory selected by the user. If the user presses Cancel, it returns an empty url. The function is used similarly to getExistingDirectory() .


2 Answers

Quite old question but I think I have a simpler solution than most for the lazy ones. You can connect the signal currentChanged of QFileDialog with a function that dynamically changes the fileMode.

//header
class my_main_win:public QMainWindow  
{
private:
    QFileDialog file_dialog;    
}

//constructor 

my_main_win(QWidget * parent):QMainWindow(parent)
{
    connect(&file_dialog,QFileDialog::currentChanged,this,[&](const QString & str)
        {
        QFileInfo info(str);
        if(info.isFile())
            file_dialog.setFileMode(QFileDialog::ExistingFile);
        else if(info.isDir())
            file_dialog.setFileMode(QFileDialog::Directory);
    });
}

And then simply call file_dialog as you would.

if(file_dialog.exec()){
    QStringList dir_names=file_dialog.selectedFiles():
}
like image 109
Spyros Mourelatos Avatar answered Oct 06 '22 00:10

Spyros Mourelatos


Connect to the currentChanged signal and then set the file mode to the currently selected item (directory or file). This is a Python3 implementation:

class GroupFileObjectDialog(QFileDialog):

    def __init__(self, parent):
        super().__init__(parent)
        self.setOption(QFileDialog.DontUseNativeDialog)
        self.setFileMode(QFileDialog.Directory)
        self.currentChanged.connect(self._selected)

    def _selected(self,name):
        if os.path.isdir(name):
            self.setFileMode(QFileDialog.Directory)
        else:
            self.setFileMode(QFileDialog.ExistingFile)

Tested on PyQt 5.14 running on linux / Ubuntu18.04.

like image 38
gerardw Avatar answered Oct 06 '22 01:10

gerardw