问题
I've been struggling with this for a while.
Qt's QFileSystemModel is really slow when fetching several hundred files because of a really bad icon fetching algorithm.
I want to completely disable icons. They are fetched in QFileSystemModel::data method which is not virtual (the source of QFileSystemModel is available here: http://qt.gitorious.org/qt/qt/blobs/4.7/src/gui/dialogs/qfilesystemmodel.cpp)
This is the code I'm trying to run:
class FileModel : public QFileSystemModel {
using QFileSystemModel::data;
public:
QVariant QFileSystemModel::data(const QModelIndex &index, int role) const
{
// my own implementation here
}
}
but it fails with
cannot define member function QFileSystemModel::data witin FileModel
UPDATE
I've managed to override the function and this is what I have now:
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();
}
};
However this code doesn't compile. This is the error I get:
'const QFileSystemModelPrivate* QFileSystemModel::d_func() const' is private
回答1:
Looks like this was anticipated, as there is a method for setting the "icon provider":
http://doc.qt.io/archives/qt-4.7/qfilesystemmodel.html#setIconProvider
The parameter, a QFileIconProvider, looks to be a fairly simple class that you can implement an instance of yourself, with a method that fetches an icon from a QFileInfo (basically, a file name):
http://doc.qt.io/archives/qt-4.7/qfileinfo.html
You could implement one of these that just returns the same icon for everything. If you find that doesn't address your problem, the following compiled fine for me...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);
}
};
回答2:
If a function in a base class is virtual then it is virtual in derived classes as well. The following will print "C":
#include <iostream>
class A {
public:
virtual void data() = 0;
};
class B: public A {
public:
void data() { std::cout << "B\n"; }
};
class C: public B {
public:
void data() { std::cout << "C\n"; }
};
int
main() {
C c;
A *a = &c;
a->data();
return 0;
}
QFileSystemDialog is derived from QAbstractItemModel in which data() is pure virtual. You couldn't even instatiate the former if it didn't override data() with its own implementation.
See http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#data
来源:https://stackoverflow.com/questions/10246984/how-to-override-re-implement-a-member-function-in-qfilesystemmodel