How to show folder with certain file name in it
-
Hello guys,
I am trying to open a dialog view that shows folders with only a certain filename "abc.txt" inside it. After searching I found that
QSortFilterProxyModel may be the solution but any body knows how to use it?
here is my code sofar@
// selecting a new ABC.txt file
QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(parent);
filterModel->setSourceModel(stringListModel);QString path; QFileDialog dialog(this); dialog.setOption(QFileDialog::ShowDirsOnly,true); dialog.setNameFilter("ABC.TXT"); dialog.setViewMode(QFileDialog::List); dialog.exec(); //path=dialog.selectedFiles();
@
-
Hi there, the QSortFilterPwoxyModel is AFAIK only used in a View/Model way. The QFileDialog does all the View/Model stuff on the background without the user to handle it. You might want to check the setNameFilters options in the QFileDialog. Never used it before, but it might work. Maybe this will work better for you:
@
QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
"/home",
QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks);
@
You will get the directory only. Then you are able to check if the dir contains your file, if not, give a pop-up that it failed.
greetz and happy coding! -
Thank you for your reply, yes but i want to avoid the pop up or to enable only folders that have the abc.txt file inside it.
Is it possible?
-
The problem with "the only show folders containing file X" is that you need to walk the disk to find all the folders that contain said file which can take a long time. You could try to use the OS file search functionality to speed that up (where available, no Qt integration either), but even then you will need to check all the folders not indexed (if the search even tells you what it is actually indexing) manually. Even if you do this in the background, the user won't be able to select anything before the folder he needs was found.
In creator we just show a normal file dialog which will only show the files we care about. That works pretty well I think.
-
1- with my current implementation it does not show only the file ABC.txt in the window, however all files are shown.
2- May be we can search for 1 level only of subfolders.
-
Hmm, oke, think you have to inherit the qfiledialog and write the code yourself. Never tried to hide the directories myself. The only think I imagine that it will be very slow to start the dialog because you will need a system wide search which directories to include.
Let me know what you come up with. Always eager to learn. -
When I change *.txt into abc.txt, files are not selectable
@
QString filename = QFileDialog::getOpenFileName(
this,
"open db",
QDir::currentPath(),
"dB file (*.txt)"
);
@ -
for using the QSortFilterProxyModel you need to use Model
in that case i think its better for you to use QFileSystemModel to provides a data model for the local filesystem.create your own class (MyClass) that inherits the QSortFilterProxyModel and implement the function:
@virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const@
and check if the folder match to your filter
something like:
@
bool MyClass::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
{
QModelIndex index = sourceModel()->index(source_row, 0/column/, source_parent);
if( sourceModel()->isDir(index) && sourceModel->hasChildren(index))
{
QString fullPath = sourceModel()->fileInfo(index).absoluteFilePath();
QDir dir(fullPath);
QStringList children = dir.entryList( QDir::Files | QDir::NoSymLinks | Dir::NoDotAndDotDot);
if( children.contain(QString("abc.txt"))
return true;
}
return false;
}after that you need to set the MyClass as your model and set it to a view like:
QFileSystemModel *model = new QFileSystemModel;
model->setRootPath(QDir::currentPath());
MyClass *myClass = new MyClass;
myClass->setSourceModel(model);QTreeView *tree = new QTreeView();
tree->setModel(myClass);
@
now you have a treeview with filtering as you ask for -
I get this error
qabstractmodel has no member isdir
any idea?
-
Here is my full code
header file myclass.h
@
#ifndef MYCLASS_H
#define MYCLASS_H#include <QDate>
#include <QSortFilterProxyModel>namespace Ui {
class myclass;
}class myclass : public QSortFilterProxyModel
{
Q_OBJECTpublic:
myclass(QObject *parent = 0);protected:
virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const;private slots:
void on_pushButton_clicked();private:
Ui::myclass *ui;
};#endif // MYCLASS_H
@
myclass.cpp
@
#include "myclass.h"
#include <QtGui>
#include <QFileInfo>
#include <QDir>
#include <QString>myclass::myclass(QObject *parent)
: QSortFilterProxyModel(parent)
{
}bool myclass::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
{
QModelIndex index = sourceModel()->index(source_row, 0/column/, source_parent);if (sourceModel()->isDir(index) && sourceModel->hasChildren(index)) { QString fullPath = sourceModel()->fileInfo(index).absoluteFilePath(); QDir dir(fullPath); QStringList children = dir.entryList( QDir::Files | QDir::NoSymLinks | Dir::NoDotAndDotDot); if( children.contain(QString("abc.txt"))) { return true; } } return false;
}
@
In Class that searches and has browse button
@
#include "myclass.h"QFileSystemModel *model = new QFileSystemModel; model->setRootPath(QDir::currentPath()); myclass *myClass = new myclass; myClass->setSourceModel(model); QTreeView *tree = new QTreeView(); tree->setModel(myClass); tree->show();
@
-
thank you lahianim. now there is only one error left
here is the new code
@
bool myclass::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
{
QFileSystemModel *sourceModel();QModelIndex index = sourceModel()->index(source_row, 0/column/, source_parent);
if ( (sourceModel()->isDir(index) && sourceModel->hasChildren(index)))
{
QString fullPath = sourceModel()->fileInfo(index).absoluteFilePath();
QDir dir(fullPath);
QStringList children = dir.entryList( QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot);if( children.contains(QString("abc.txt"))) { return true; } } return false;
}
@
Error:
request for member 'hasChildren' in 'sourceModel' which is of non-class type 'QFileSystemModel * ()()'
-
I made some changes according to this website but I get an error
http://stackoverflow.com/questions/2101100/qfiledialog-filtering-folders/2126060#2126060
can any body help?My Code
@ h file#ifndef MYCLASS_H
#define MYCLASS_H#include <QDate>
#include <QSortFilterProxyModel>namespace Ui {
class myclass;
}class myclass : public QSortFilterProxyModel
{
Q_OBJECTpublic:
myclass(QObject *parent = 0);protected:
virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const;private slots:
void on_pushButton_clicked();private:
Ui::myclass *ui;
};#endif // MYCLASS_H
@cpp
@
#include "myclass.h"
#include <QtGui>
#include <QFileInfo>
#include <QDir>
#include <QString>
#include <QStringList>myclass::myclass(QObject *parent)
: QSortFilterProxyModel(parent)
{
}bool myclass::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
{QModelIndex index = sourceModel()->index(source_row, 0/column/, source_parent);
QFileSystemModel* filemodel = qobject_cast<QFileSystemModel*>(sourceModel());if ( (filemodel->isDir(index)) && (filemodel->hasChildren(index)))
{
qDebug() << filemodel->fileName(index);
QString fullPath = filemodel->fileInfo(index).absoluteFilePath();
QDir dir(fullPath);
QStringList children = dir.entryList( QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot);if( children.contains(QString("abc.txt"))) { return true; } } return false;
}
@
I call it this way
@
QFileDialog dialog;
myclass* proxyModel = new myclass();
dialog.setProxyModel(proxyModel);
dialog.exec();
@Error:
symbols not found for architect x86_64
collect 2: Id returned 1 exit status -
I am building on mac with QT Creater 2.4.1 based on QT 4.7.4
-
Now it compiles well. However, I want to show only files called abc.txt. I still don't know where is the file name in which variables. Any help?
header
@
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QSortFilterProxyModel>
class myclass : public QSortFilterProxyModel
{
Q_OBJECTpublic:
explicit myclass(QObject *parent = 0);protected:
bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const;
};#endif // MYCLASS_H
@@
#include "myclass.h"
#include <QtGui>
#include <QFileInfo>
#include <QDir>
#include <QString>
#include <Qdebug>myclass::myclass(QObject *parent)
: QSortFilterProxyModel(parent)
{
}bool myclass::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
{
QModelIndex index = sourceModel()->index(source_row, 0/column/, source_parent);
QFileSystemModel* filemodel = qobject_cast<QFileSystemModel*>(sourceModel());qDebug() << filemodel->fileName(index) << filemodel->isDir(index) << filemodel->hasChildren(index); if (filemodel->fileName(index).contains("abc.txt", Qt::CaseInsensitive)) { return true; } else { return false; }
}
@
-
Hi
if you still using this:bq. QFileDialog dialog;
myclass* proxyModel = new myclass();
dialog.setProxyModel(proxyModel);
dialog.exec();you need to set the source model to the proxy model like before:
bq. QFileSystemModel *model = new QFileSystemModel;
model->setRootPath(QDir::currentPath());
MyClass *myClass = new MyClass;
myClass->setSourceModel(model);
QTreeView *tree = new QTreeView();
tree->setModel(myClass); -
I don't get the file info but the directory structure
"/"
"/Volumes/DATA/MAC/login-build-desktop-Desktop_Qt_4_7_3_for_GCC__Qt_SDK__Debug/login.app/Contents/MacOS"
"/Volumes/DATA/MAC/login-build-desktop-Desktop_Qt_4_7_3_for_GCC__Qt_SDK__Debug/login.app/Contents"
"/Volumes/DATA/MAC/login-build-desktop-Desktop_Qt_4_7_3_for_GCC__Qt_SDK__Debug/login.app"
"/Volumes/DATA/MAC/login-build-desktop-Desktop_Qt_4_7_3_for_GCC__Qt_SDK__Debug"
"/Volumes/DATA/MAC/tt-build-desktop-Desktop_Qt_4_7_3_for_GCC__Qt_SDK__Debug"
"/Volumes/DATA/MAC"
"/Volumes/DATA"
"/Users"
"/Volumes"
QFileInfo::absolutePath: Constructed with empty filename
2012-08-12 12:43:07.026 login[37625:407] Invalid URL passed to an open/save panel: '(null)'. Using 'file://localhost/Volumes/DATA/MAC/tt-build-desktop-Desktop_Qt_4_7_3_for_GCC__Qt_SDK__Debug/' instead.
2012-08-12 12:43:07.786 login[37625:407] Invalid URL passed to an open/save panel: '(null)'. Using 'file://localhost/Volumes/DATA/MAC/tt-build-desktop-Desktop_Qt_4_7_3_for_GCC__Qt_SDK__Debug/' instead.
"/"and when I do qDebug () << info.fileName();
I get the folders without the path@
void Login::on_loginbrowse_clicked()
{
// selecting a new setting.dB file
//QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(parent);
//filterModel->setSourceModel(stringListModel);QFileSystemModel *model = new QFileSystemModel; model->setRootPath(QDir::currentPath()); myclass *myClass = new myclass (this); myClass->setSourceModel(model); QFileDialog *dialog = new QFileDialog; dialog->setDirectory(qApp->applicationDirPath()); dialog->setProxyModel(myClass); dialog->exec();
}
@myclass
@#include "myclass.h"
#include <QtGui>
#include <QFileInfo>
#include <QDir>
#include <QString>
#include <Qdebug>myclass::myclass(QObject *parent)
: QSortFilterProxyModel(parent)
{
}bool myclass::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
{
QModelIndex index = sourceModel()->index(source_row, 0/column/, source_parent);
QFileSystemModel* filemodel = qobject_cast<QFileSystemModel*>(sourceModel());
// QFileSystemModel filemodel = static_cast<QFileSystemModel>(sourceModel());
filemodel->setRootPath(QDir::currentPath());
QFileInfo info(filemodel->filePath(index));
QString filePath = info.absoluteFilePath();
QString fullPath = filemodel->fileInfo(index).absoluteFilePath();
qDebug () << filePath;if (info.fileName().contains("Setting")) { return true; } return false;
}
@
Header
@
#ifndef MYCLASS_H
#define MYCLASS_H#include <QSortFilterProxyModel>
class myclass : public QSortFilterProxyModel
{
Q_OBJECTpublic:
explicit myclass(QObject *parent = 0);protected:
bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const;
};#endif // MYCLASS_H
@
-
can you send me a working example. Please the full code, i am not accustomed to the terminologies used.
-
the following code works for me. i tested it on win7 but this QT so it need to run on MAC too.
myfilterproxy.h
@
#ifndef MYFILTERPROXY_H
#define MYFILTERPROXY_H#include <QSortFilterProxyModel>
class MyFilterProxy : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit MyFilterProxy(QObject *parent = 0);protected:
bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const;};
#endif // MYFILTERPROXY_H
@myfilterproxy.cpp
@
#include "myfilterproxy.h"
#include <QDir>
#include <QFileSystemModel>
#include <QStringList>MyFilterProxy::MyFilterProxy(QObject *parent) :
QSortFilterProxyModel(parent)
{
}bool MyFilterProxy::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
{QModelIndex index = ((QFileSystemModel*)sourceModel())->index(source_row, 0/*column*/, source_parent); if( ((QFileSystemModel*)sourceModel())->isDir(index) && ((QFileSystemModel*)sourceModel())->hasChildren(index)) { QString fullPath = ((QFileSystemModel*)sourceModel())->fileInfo(index).absoluteFilePath(); QDir dir(fullPath); QStringList children = dir.entryList( QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot); if( children.contains(QString("abc.txt")) ) return true; } return false;
}
@main.cpp
@
#include <QtGui/QApplication>
#include <QFileDialog>
#include "myfilterproxy.h"int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyFilterProxy myProxy;
QFileDialog fileDialog;
//its your call if to use this line (or default or other view mode)
fileDialog.setViewMode(QFileDialog::Detail);
fileDialog.setProxyModel(&myProxy);
fileDialog.exec();
return a.exec();
}
@i'll hope it help you.