PDA

View Full Version : QFileDialog to select files AND folders



superpacko
11th August 2011, 14:13
The problem that i have i that QFileDialog doesnt seem to support choosing files or folders. FileMode flags dont have one that mixes both.


Is there any way to make a QFileDialog able to select files and folders?

FileMode::AnyFiles let you select a file, but if you choose a folder it opens it and shows you the files in it and FileMode::Directory only let you select folders. Since im doing a compressor i must allow the user to select files, folders, or both at the same time (multiple files and folders). Is there any other way that doesnt require craeting a new dialog from scratch?

thanks!

ijab
15th May 2012, 05:31
I tried to handle the same problem and I found a solution after searching in QT forums. The following is the codes that you could try:

QFileDialog* _f_dlg = new QFileDialog(this);
_f_dlg->setFileMode(QFileDialog::Directory);
_f_dlg->setOption(QFileDialog::DontUseNativeDialog, true);

// Try to select multiple files and directories at the same time in QFileDialog
QListView *l = _f_dlg->findChild<QListView*>("listView");
if (l) {
l->setSelectionMode(QAbstractItemView::MultiSelection );
}
QTreeView *t = _f_dlg->findChild<QTreeView*>();
if (t) {
t->setSelectionMode(QAbstractItemView::MultiSelection );
}

int nMode = _f_dlg->exec();
QStringList _fnames = _f_dlg->selectedFiles();

superpacko
15th May 2012, 15:16
Thanks! that's a nice workaround! i'll try it

tranhuanltv
16th April 2013, 12:59
This is the way i'm make it possible, by subclass QFileDialog, connect "Choose" button signal to yourself slot, and always setEnable(true) for "Choose" button


//Subclass QFileDialog for customize allow select both file/folder
class FileDialog : public QFileDialog{
Q_OBJECT
private:
QListView *m_listView;
QTreeView *m_treeView;
QPushButton *m_btnOpen;
QStringList m_selectedFiles;

public slots:
void chooseClicked();
public:
FileDialog();
QStringList selectedFiles();
bool eventFilter(QObject* watched, QEvent* event);
};




FileDialog::FileDialog() : QFileDialog()
{
m_btnOpen = NULL;
m_listView = NULL;
m_treeView = NULL;
m_selectedFiles.clear();

this->setOption(QFileDialog::DontUseNativeDialog, true);
this->setFileMode(QFileDialog::Directory);
QList<QPushButton*> btns = this->findChildren<QPushButton*>();
for (int i = 0; i < btns.size(); ++i) {
QString text = btns[i]->text();
if (text.toLower().contains("open") || text.toLower().contains("choose"))
{
m_btnOpen = btns[i];
break;
}
}

if (!m_btnOpen) return;

m_btnOpen->installEventFilter(this);
//connect(m_btnOpen, SIGNAL(changed()), this, SLOT(btnChanged()))
m_btnOpen->disconnect(SIGNAL(clicked()));
connect(m_btnOpen, SIGNAL(clicked()), this, SLOT(chooseClicked()));


m_listView = findChild<QListView*>("listView");
if (m_listView) {
m_listView->setSelectionMode(QAbstractItemView::ExtendedSelect ion);
}

m_treeView = findChild<QTreeView*>();
if (m_treeView) {
m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelect ion);
}

}

bool FileDialog::eventFilter( QObject* watched, QEvent* event )
{
QPushButton *btn = qobject_cast<QPushButton*>(watched);
if (btn)
{
if(event->type()==QEvent::EnabledChange) {
if (!btn->isEnabled()) {
btn->setEnabled(true);
}
}
}

return QWidget::eventFilter(watched, event);
}


void FileDialog::chooseClicked()
{
QModelIndexList indexList = m_listView->selectionModel()->selectedIndexes();
foreach (QModelIndex index, indexList)
{
if (index.column()== 0)
{
m_selectedFiles.append(this->directory().absolutePath() + index.data().toString());
}
}

QDialog::accept();
}

QStringList FileDialog::selectedFiles()
{
return m_selectedFiles;
}