1

I have a requirement to display file selection dialogue. I can't use QFileDialog as we need to restrict the user access to the file system. I created a subclass of QDialog which has 2 QTreeViews; first one for displaying directories only and the second one for displaying files only. I have 2 QFileSystemModels to serve content to these views, of which directory listing model is working as expected, but not file list model. File list model/view is not always showing the files, sometimes even showing files from parent directory and previous directory.

How to display only files from the directory selected in the first (directory tree) view?

Following is the code snippet I tried.

FileDialogue1::FileDialogue1(const QStringList& locs, QWidget* prnt)
    : QDialog(prnt)
{
    QHBoxLayout* hlayout = new QHBoxLayout(this);
    m_splitter = new QSplitter(this);
    m_dir_view = new QTreeView(m_splitter);
    m_dir_model = new QFileSystemModel(m_dir_view);
    m_dir_model->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs);
    m_dir_view->setModel(m_dir_model);
    connect(m_dir_view, SIGNAL(clicked(QModelIndex)), SLOT(loadFileList(QModelIndex)));
    m_file_view = new QTreeView(m_splitter);
    m_file_model = new FileSystemModel(m_file_view);
    m_file_model->setFilter(QDir::NoDotAndDotDot | QDir::Files);
    m_file_view->setModel(m_file_model);

    // restrict user selection
    QGroupBox* locs_gb = new QGroupBox(tr("Available locations"), this);
    QVBoxLayout* vlayout = new QVBoxLayout(locs_gb);
    QSignalMapper* mapper = new QSignalMapper(locs_gb);
    connect(mapper, SIGNAL(mapped(QString)), SLOT(changeLocation(QString)));
    foreach (const QString& loc, locs)
    {
        QRadioButton* radio = new QRadioButton(loc, locs_gb);
        vlayout->addWidget(radio, 0, Qt::AlignTop | Qt::AlignLeft);
        connect(radio, SIGNAL(clicked()), mapper, SLOT(map()));
        mapper->setMapping(radio, loc);
    }
    vlayout->addStretch(1);

    hlayout->addWidget(locs_gb, 0, Qt::AlignLeft);
    hlayout->addWidget(m_splitter);

    setMinimumSize(MIN_SIZE);
}


void FileDialogue1::changeLocation(const QString& path)
{        
    m_dir_view->setRootIndex(m_dir_model->setRootPath(path));
}    

void FileDialogue1::loadFileList(const QModelIndex& idx)
{        
    const QString path(m_dir_model->fileInfo(idx).absolutePath());
    m_file_view->setRootIndex(m_file_model->setRootPath(path));        
}

Thanks in advance.

ramtheconqueror
  • 1,907
  • 1
  • 22
  • 35

1 Answers1

1

I believe the problem you have when you see no files is due to the way you set the filter flags for the QFileSystemDialog: -

m_file_model->setFilter(QDir::NoDotAndDotDot | QDir::Files);

If you look at all of the possible options for filters it includes flags such as these: -

  • QDir::Readable (show all readable files)
  • QDir::Writable (show all writable files)
  • Dir::Executable (show all executable files)
  • etc.

By setting just QDir::NoDotAndDotDot and QDir::Files you're eliminating all of those options.

Instead, set the filters you want based on the default set. For example: -

m_file_model->setFilter(m_file_model->filter() | QDir::NoDotAndDotDot | ~QDir::Dirs);

Which would ensure the '.' and '..' paths as well as directories are excluded.

In this example, we modify the current model's filters and use the not flag (~) to exclude directories in this case.

TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85