为什么我的 QSortFilterProxyModel 在与 QStandardItemModel 一起使用时会向我的 TreeView 添加额外的空白行?

问题描述

我有一个 TreeView,它使用的模型是 QSortFilterProxyModel,QSortFilterProxyModel 的源模型是 QStandardItemmodel。

当 Treeview 直接使用 QStandardItemmodel 时,我没有得到额外的行,但过滤不起作用。当我使用过滤器时,我添加了一堆空行,但我不知道为什么。

ParentFolderModel.cpp(QStandardItemmodel 子类)

代码改编自此处https://arunpkqt.wordpress.com/2017/01/05/custom-filesystemmodel-display/

#include "parentfoldermodel.h"

ParentFolderModel::ParentFolderModel(QObject *parent)
    :QStandardItemmodel(parent)
{
    rootItem = this->invisibleRootItem();
    dirIcon = QApplication::style()->standardIcon(qstyle::SP_DirIcon);
    fileIcon = QApplication::style()->standardIcon(qstyle::SP_MediaPlay);
    disabledIcon = QApplication::style()->standardIcon(qstyle::SP_DialogIgnoreButton);
}
ParentFolderModel::~ParentFolderModel()
{
}


void ParentFolderModel::buildfiletree(const QString name)
{
    QStandardItem* parent = new QStandardItem(dirIcon,name);
    parent->setAccessibleDescription(name);
    rootItem->appendRow(parent);
    createDirectoryItem(name,parent);
}

void ParentFolderModel::createDirectoryItem(QString dirName,QStandardItem *parentItem)
{
    QDir dir(dirName);
    QFileInfo folderName;
    QStandardItem* child;
    QString fileName,filePath;
    QFileInfoList subFolders = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NodotAndDotDot);
    foreach (folderName,subFolders)
    {
        fileName = folderName.fileName();
        if(folderName.isFile())
        {
            child = new QStandardItem(fileIcon,fileName);
        }

        else child = new QStandardItem(dirIcon,fileName);

        filePath = folderName.filePath();
        child->setEditable(false);
        child->setAccessibleDescription(filePath);
        parentItem->appendRow(child);
        createDirectoryItem(filePath,child);
    }
}

FileFilterModel.cpp(QSortFilterProxyModel 子类)

#include "filefiltermodel.h"

FileFilterModel::FileFilterModel(QObject *parent)
{

}

bool FileFilterModel::filteracceptsRow(int sourceRow,const QModelIndex &sourceParent) const
{
    QModelIndex index0 = sourceModel()->index(sourceRow,this->filterKeyColumn(),sourceParent);

    if (!index0.isValid())
        return QSortFilterProxyModel::filteracceptsRow(sourceRow,sourceParent);

    if (sourceModel()->data(index0).toString().contains(this->filterRegularExpression()))
        return true;

    int rows = sourceModel()->rowCount(index0);
    for (int row = 0; row < rows; row++) {
        if (filteracceptsRow(row,index0))
            return true;
    }

     QString key = sourceModel()->data(index0,filterRole()).toString();
     return key.contains(filterRegExp()) ;
}

MainWindow.cpp

#include "mainwindow.h"
#include "./ui_mainwindow.h"
// this is where the models are being init
MainWindow::MainWindow(QWidget* parent): QMainWindow(parent),ui(new Ui::MainWindow){
    filemodel = new ParentFolderModel(this);
    fileFilterModel = new FileFilterModel(this);
    fileFilterModel->setSourceModel(filemodel);
    ui->filetreeView->setModel(fileFilterModel);
    ui->filetreeView->setHeaderHidden(true);
}

// once the user selects a folder the QStandardItemmodel will get populated with the dirs and files
void MainWindow::on_actionManage_Folders_triggered()
{
    ui->progressLabel->setText("Adding folder");
    QString folderName = QFileDialog::getExistingDirectory(this,"Select Folder",QDir::homePath());
    QFuture<void> populate = QtConcurrent::run(this->filemodel,&ParentFolderModel::buildfiletree,folderName);
    watcher.setFuture(populate);
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)