如何在 QFileSystemModel 中重写(重新实现)成员函数

How to override (re-implement) a member function in QFileSystemModel

本文关键字:实现 成员 函数 新实现 QFileSystemModel 重写      更新时间:2023-10-16

我已经为此苦苦挣扎了一段时间。

Qt的QFileSystemModel在获取数百个文件时非常慢,因为图标获取算法非常糟糕。

我想完全禁用图标。它们是在QFileSystemModel::data非虚拟方法中获取的(QFileSystemModel 的源代码可在此处获得:http://qt.gitorious.org/qt/qt/blobs/4.7/src/gui/dialogs/qfilesystemmodel.cpp)

这是我尝试运行的代码:

class FileModel : public QFileSystemModel {
    using QFileSystemModel::data;
public:
    QVariant QFileSystemModel::data(const QModelIndex &index, int role) const
    {
     // my own implementation here
    }
}

但它失败了

cannot define member function QFileSystemModel::data witin FileModel

更新

我已经设法覆盖了该函数,这就是我现在拥有的:

class FileModel : public QFileSystemModel {
public:
    QVariant data(const QModelIndex &index, int role) const
    {
    // Here goes Qt's implementation
    Q_D(const QFileSystemModel);
    if (!index.isValid() || index.model() != this)
        return QVariant();
    switch (role) {
    case Qt::EditRole:
    case Qt::DisplayRole:
        switch (index.column()) {
        case 0: return d->name(index);
        case 1: return d->size(index);
        case 2: return d->type(index);
        case 3: return d->time(index);
        default:
            qWarning("data: invalid display value column %d", index.column());
            break;
        }
        break;
    case FilePathRole:
        return filePath(index);
    case FileNameRole:
        return d->name(index);
    case Qt::DecorationRole:
        if (index.column() == 0) {
            QIcon icon = d->icon(index); // This is the part I need to change
            if (icon.isNull()) {
                if (d->node(index)->isDir())
                    icon = d->fileInfoGatherer.iconProvider()->icon(QFileIconProvider::Folder);
                else
                    icon = d->fileInfoGatherer.iconProvider()->icon(QFileIconProvider::File);
            }
            return icon;
        }
        break;
    case Qt::TextAlignmentRole:
        if (index.column() == 1)
            return Qt::AlignRight;
        break;
    case FilePermissions:
        int p = permissions(index);
        return p;
    }
    return QVariant();
}
};

但是,此代码无法编译。这是我得到的错误: 'const QFileSystemModelPrivate* QFileSystemModel::d_func() const' is private

看起来这是意料之中的,因为有一种设置"图标提供程序"的方法:

http://doc.qt.io/archives/qt-4.7/qfilesystemmodel.html#setIconProvider

参数, a QFileIconProvider ,看起来是一个相当简单的类,您可以使用从QFileInfo获取图标(基本上是文件名)的方法实现自己的实例:

http://doc.qt.io/archives/qt-4.7/qfileinfo.html

您可以实现其中之一,它只为所有内容返回相同的图标。 如果您发现这不能解决您的问题,以下编译对我来说很好......FWIW:

class FileModel : public QFileSystemModel {
public:
    QVariant data(const QModelIndex &index, int role) const
    {
        if (role == Qt::DecorationRole) {
            return QVariant (QIcon ());
        }    
        return QFileSystemModel::data(index, role);
    }
};

如果基类中的函数是虚拟的,那么它在派生类中也是虚拟的。以下内容将打印"C":

#include <iostream>
class A {
public:
  virtual void data() = 0;
};
class B: public A {
public:
  void data() { std::cout << "Bn"; }
};
class C: public B {
public:
  void data() { std::cout << "Cn"; }
};
int
main() {
  C c;
  A *a = &c;
  a->data();
  return 0;
}

QFileSystemDialog派生自QAbstractItemModel,其中data()是纯虚拟的。如果前者没有用自己的实现覆盖data(),你甚至无法确定前者。

请参阅 http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#data