我正在尝试实现自己的qfilesystemmodel。我的项目可以编译并运行,项目中的视图不显示模型中的任何内容。 我读到错误可能出在data(),parent()函数中,并且我正在堆栈而不是堆中创建模型。如有必要,我可以为您提供其他函数的实现。要创建UI,我使用了Qt Designer来自模型的数据是表示绝对路径的QString。这是我的代码。
mainwindow.h
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
FileSystemModel *pFSmodel;
};
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
pFSmodel = new FileSystemModel(QDir::homePath, this)
ui->leftList->setModel(pFSmodel);
ui->leftList->setRootIndex(pFSmodel->index(QDir::homePath()));
ui->rightList->setModel(pFSmodel);
ui->rightList->setRootIndex(pFSmodel->index(QDir::homePath()));
}
MainWindow::~MainWindow()
{
delete ui;
}
FileSystemModel.h
class FileSystemModel : public QAbstractItemModel
{
Q_OBJECT
public:
FileSystemModel(QString rootPath, QObject *parent = 0);
~FileSystemModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
QModelIndex index(QString rootPath);
QModelIndex parent(const QModelIndex &index) const;
QFileInfo fileInfo(const QModelIndex &index);
void fetchMore(const QModelIndex &parent);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
bool hasChildren(const QModelIndex &parent) const;
bool canFetchMore(const QModelIndex &parent) const;
private:
void setupModelData(const QString &rootPath);
FileItem* itemForIndex(const QModelIndex& index)const;
FileItem *rootItem_p;
QFileIconProvider iconProvider;
};
FileSystemModel.cpp
FileSystemModel::FileSystemModel(QString rootPath, QObject *parent_p):
QAbstractItemModel(parent_p)
{
rootItem_p = new FileItem(QVariant(rootPath), true, nullptr);
setupModelData(rootPath);
}
QModelIndex FileSystemModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
if (FileItem *childItem_p = itemForIndex(index)){
if (FileItem *parentItem_p = childItem_p->parentItem()){
if (parentItem_p == rootItem_p)
return QModelIndex();
if (FileItem *grandParentItem_p = parentItem_p->parentItem()){
int row = grandParentItem_p->rowOfChild(parentItem_p);
return createIndex(row, 0, parentItem_p);
}
}
}
return QModelIndex();
}
QVariant FileSystemModel::data(const QModelIndex &index, int role) const
{
if (!rootItem_p || !index.isValid() || index.column() < 0 || index.column() > columnCount())
return QVariant();
if (FileItem *item_p = itemForIndex(index)){
if (role == Qt::DisplayRole){
QVariant variant = QVariant(item_p->data(0));
return variant;
}
QVariant data = item_p->data(0);
if (role == Qt::DecorationRole && data.isValid()){
QFileInfo info = QFileInfo(data.toString());
return iconProvider.icon(info);
}
}
return QVariant();
}
void FileSystemModel::setupModelData(const QString &rootPath)
{
QDirIterator it(rootPath);
beginResetModel();
rootItem_p = new FileItem(QVariant(rootPath), true, 0);
rootItem_p->set_fetched(true);
rootItem_p->set_exist(true);
while (it.hasNext()){
it.next();
QFileInfo fileInfo = it.fileInfo();
FileItem *item_p = new FileItem(fileInfo.absoluteFilePath(), fileInfo.isDir(), rootItem_p);
item_p->set_fetched(true);
item_p->set_exist(true);
rootItem_p->addChild(item_p);
}
endResetModel();
}
QModelIndex FileSystemModel::index(QString rootPath)
{
QPair<FileItem*, int> pr = rootItem_p->findItem(QVariant(rootPath));
if (pr.first == nullptr)
return QModelIndex();
else{
FileItem *item_p = pr.first;
int row = pr.second;
return createIndex(row, 0, item_p);
}
}
FileItem.h
class FileItem{
public:
FileItem(QVariant maybeFilePath, bool fileIsDir, FileItem *parentItem_p);
FileItem();
~FileItem();
void addChild(FileItem *child_p);
FileItem *child(int row);
int childCount() const;
int columnCount() const;
int row() const;
int rowOfChild(FileItem *child_p) const;
QVariant data(int column) const;
FileItem *parentItem();
QPair<FileItem*, int> findChild(Predicate pred);
QPair<FileItem*, int> findItem(Predicate pred);
QPair<FileItem*, int> findChild(QVariant data);
QPair<FileItem*, int> findItem(QVariant data);
void set_dir(bool status);
void set_fetched(bool status);
void set_exist(bool status);
bool checkDir()const;
bool checkFetched()const;
bool checkExist()const;
private:
bool exist;
bool is_dir;
bool is_fetched;
FileItem *parentItem_p;
QVector<FileItem*> childrenPtrs;
QVariant itemData;
};