Reputation: 1265
I'm using the code below to build a qstringlist of filenames:
QStringList filenames = QFileDialog::getOpenFileNames(this,"",QDir::currentPath() );
How can I change this so I can select directories as well?
I looked at:
dialog.setFileMode(QFileDialog::AnyFile);
but I don't get how to use it with my code.
Upvotes: 1
Views: 4887
Reputation: 1
I encountered with the same problem as @Filip answered above, the choose button has wrong status when only choose one file.
According to the code (qt5.12) call stack, it's QFileDialogPrivate::_q_updateOkButton
block set the button disabled.
as it's difficult to access and modify qfiledialogPrivate and also to keep my derived dialog simple, my idea is that install a eventfilter on derived dialog class and set button enabled here.it does works.
1.Install eventfilter.
{
QListView* plist = findChild<QListView*>();
QTreeView* ptree = findChild<QTreeView*>();
if(plist)
{
plist->setSelectionMode(QAbstractItemView::ExtendedSelection);
plist->viewport()->installEventFilter(this);
}
if(ptree)
{
ptree->setSelectionMode(QAbstractItemView::ExtendedSelection);
ptree->viewport()->installEventFilter(this);
}
}
void CMyDialogEx::OnhandleButtons()
{
QDialogButtonBox* pButtonBox = findChild<QDialogButtonBox*>();
if(pButtonBox)
{
QList<QAbstractButton*> vButtons = pButtonBox->buttons();
for(int i = 0; i < vButtons.count(); i++)
{
QAbstractButton *pItem = vButtons.at(i);
if( pItem == nullptr)
continue;
if(pItem->isEnabled())
continue;
if(pButtonBox->buttonRole(pItem) == QDialogButtonBox::AcceptRole)
{
pItem->setEnabled(true);
break;
}
}
}
}
bool CMyDialogEx::eventFilter(QObject *watched, QEvent *event)
{
if(event->type() == QEvent::MouseButtonRelease)
{
QObject *pParent = watched->parent();
bool bTargetObj = dynamic_cast<QTreeView*>(watched) != nullptr
|| dynamic_cast<QListView*>(watched) != nullptr
|| dynamic_cast<QTreeView*>(pParent) != nullptr
|| dynamic_cast<QListView*>(pParent) != nullptr;
if(bTargetObj)
OnhandleButtons();
}
return false;
}
Now, the button responses correctly when just choose one file, but when click it, nothing happened, cause insde the QFiledialog::accept()
, there are some filemode judgment. Just overwrite the function ,or use singal and slot.
Upvotes: 0
Reputation: 1
I tried this, but the result in my case is a bit strange: I can select a combination of folders and files, as long as the first selected item is a folder.
So when I select a folder, then a file and again a folder, I can proceed clicking the button and retrieving the results: see screenshot in link below.
First folder selected, then file: OK
However, when the first item is a file (followed by a folder, or just a file), the button to proceed is not available... So just selecting one or multiple files is not available to me in this implementation it seems, as can be seen in the other screenshot:
First file selected, then folder: not able to proceed
Is there any way using the same code using QFileDialog that allows you to
Upvotes: 0
Reputation: 1265
This code snippet linked in the comment above solves my issue.
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();
Upvotes: 2