segv when getting QFileInfo from subclassed QFileSystemModel
-
Context:
I am creating a directory browser using a QTableView & a subclassed QFileSystemModel due to its already existing file browser functionality.
I am using 5 columns, first column [0] is 128px wide, the rest spaced out in widths respectively are
6, 9, 3, 2
all which I set in the class containing both theQTableWidget
andQFileSystemModel
.[0] Icon (default icon for folder or file, except in the case of an image where the image icon is loaded from cache) [1] File name [2] File location (relative to a specific directory) [3] Last date modified of the file [4] File size (formatted to human readable
Problem:
On implementing the QAbstractItemView::doubleClick (
QTableView
) to enter a directory and set the new root model index(i.e. browse into a set directory).When double-clicking on a cell:
// Connect on list widget cell click to browse into directory or open file connect(ui->customTableView, &QTableView::doubleClicked, this, [this](const QModelIndex & index) { QFileInfo fi = model->getFileInfo(index); QString newPath = fi.filePath(); changeDirectory(newPath); });
-
I query the model for the fileInfo entry (created a get method due for testing due to
fileInfo(const QModexIndex&)
wasn't working).QFileInfo FileSystemModel::getFileInfo(const QModelIndex& index) { QFileInfo mfileInfo = QFileInfo(fileInfo(index)); return mfileInfo; }
-
Inside of the model, I ask for the
QFileInfo
object usingfileInfo(index)
which then results in a segv on a sharedpointer.
See details below.
Debugger output
Locals index @0x32d3dfd0 QModelIndex & c 1 int i 853000288 quintptr m @0x32d7a548 FileSystemModel [QFileSystemModel] @0x32d7a548 QFileSystemModel [d] @0x32d79b58 QFileSystemModelPrivate [parent] 0x0 QObject * [children] <0 items> [properties] <at least 0 items> [methods] <0 items> [extra] COLUMN_DATE_MODIFIED 3 int COLUMN_FILENAME 1 int COLUMN_ICON 0 int COLUMN_LOCATION 2 int COLUMN_SIZE 4 int dataPath "H:/debug/Root" QString locale @0x32d7a558 QLocale mimeDb @0x32d7a550 QMimeDatabase staticMetaObject @0x53a4c0 QMetaObject r 0 int mfileInfo <not accessible> QFileInfo this 0xbaadf00d FileSystemModel* Inspector Expressions Return Value Tooltip
Stack Trace Output
1 QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData>>::operator-> qscopedpointer.h 118 0x207175ea 2 qGetPtrHelper<QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData>>> qglobal.h 1055 0x207175ea 3 QFileSystemModel::d_func qfilesystemmodel.h 152 0x207175ea 4 QFileSystemModel::fileInfo qfilesystemmodel.cpp 169 0x207175ea 5 FileSystemModel::getFileInfo filesystemmodel.cpp 85 0x48ca6a 6 ExplorerDialog::<lambda(const QModelIndex&)>::operator()(const QModelIndex &) const ExplorerView.cpp 418 0x44e3e6 7 QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<const QModelIndex&>, void, ExplorerDialog::setupListWidget()::<lambda(const QModelIndex&)>>::call(ExplorerDialog::<lambda(const QModelIndex&)> &, void * *) qobjectdefs_impl.h 146 0x45b0e9 8 QtPrivate::Functor<ExplorerDialog::setupListWidget()::<lambda(const QModelIndex&)>, 1>::call<QtPrivate::List<QModelIndex const&>, void>(ExplorerDialog::<lambda(const QModelIndex&)> &, void *, void * *) qobjectdefs_impl.h 256 0x45aca1 9 QtPrivate::QFunctorSlotObject<ExplorerDialog::setupListWidget()::<lambda(const QModelIndex&)>, 1, QtPrivate::List<const QModelIndex&>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void * *, bool *) qobjectdefs_impl.h 439 0x459f5b 10 QtPrivate::QSlotObjectBase::call qobjectdefs_impl.h 394 0x65c8161 11 QMetaObject::activate qobject.cpp 3789 0x65c8161 12 QMetaObject::activate qobject.cpp 3660 0x65c851b 13 QAbstractItemView::doubleClicked moc_qabstractitemview.cpp 661 0x207519a6 14 QAbstractItemView::mouseDoubleClickEvent qabstractitemview.cpp 1964 0x2075dd0a //...
Image of crash
Full Code Example (mostly adapted from
::data()
found here) :Header file
#ifndef FILESYSTEMMODEL_H #define FILESYSTEMMODEL_H #include <QFileSystemModel> #include <QMimeDatabase> #include "libs/global.h" #include "libs/imagecachehelper.h" class FileSystemModel : public QFileSystemModel { Q_OBJECT public: FileSystemModel(QString dataPath); // QAbstractItemModel interface public: QMimeDatabase mimeDb; QVariant data(const QModelIndex& index, int role) const; QFileInfo getFileInfo(const QModelIndex& index); private: static const int COLUMN_ICON = 0; static const int COLUMN_FILENAME = 1; static const int COLUMN_LOCATION = 2; static const int COLUMN_DATE_MODIFIED = 3; static const int COLUMN_SIZE = 4; QString dataPath; QLocale locale; // QAbstractItemModel interface public: QVariant headerData(int section, Qt::Orientation orientation, int role) const; // QAbstractItemModel interface public: int columnCount(const QModelIndex& parent) const; }; #endif // FILESYSTEMMODEL_H
and implementation
#include "filesystemmodel.h" FileSystemModel::FileSystemModel(QString path): dataPath(path) { dataPath = QString(path); setRootPath(dataPath); setFilter(QDir::Files | QDir::Filter::Dirs | QDir::Filter::NoDotAndDotDot); sort(COLUMN_FILENAME, Qt::SortOrder::AscendingOrder); } QVariant FileSystemModel::data(const QModelIndex& index, int role) const { // Q_D(const QFileSystemModel); if (!index.isValid() || index.model() != this) return QVariant(); switch (role) { case Qt::EditRole: break; case Qt::DisplayRole: switch (index.column()) { case COLUMN_FILENAME: return fileInfo(index).fileName(); case COLUMN_LOCATION: { QFileInfo fi = fileInfo(index); QString s = fi.filePath(); QString localReplace = s.replace(dataPath, "/Root"); return localReplace; } case COLUMN_DATE_MODIFIED: return Global::dateToQString(fileInfo(index).lastModified());; case COLUMN_SIZE: { QFileInfo fi = fileInfo(index); if (fi.isDir()) { return QString("--"); } else { return locale.formattedDataSize(fi.size()); } }; default: return QVariant(); } break; case FilePathRole: return filePath(index); case FileNameRole: return fileName(index); case Qt::DecorationRole: if (index.column() == COLUMN_ICON) { QFileInfo fi = fileInfo(index); if (fi.isFile()) { QPixmap p = QPixmap(fi.filePath()); if (p.isNull()) { return QFileSystemModel::iconProvider()->icon(fi); } p.scaled(ImageHelper::getCacheImageSize()); return QIcon(p); } else { return QFileSystemModel::iconProvider()->icon(fi); } } break; case Qt::TextAlignmentRole: switch (index.column()) { case COLUMN_FILENAME: case COLUMN_LOCATION: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); case COLUMN_DATE_MODIFIED: return QVariant(Qt::AlignCenter); case COLUMN_SIZE: return QVariant(Qt::AlignRight | Qt::AlignVCenter); case COLUMN_ICON: default: return QVariant(Qt::AlignCenter); } } return QFileSystemModel::data(index, role); } QFileInfo FileSystemModel::getFileInfo(const QModelIndex& index) { QFileInfo mfileInfo = QFileInfo(fileInfo(index)); return mfileInfo; } QVariant FileSystemModel::headerData(int section, Qt::Orientation orientation, int role) const { switch (role) { case Qt::DisplayRole: { switch (section) { case COLUMN_ICON: return tr("Preview"); case COLUMN_FILENAME: return tr("Name"); case COLUMN_LOCATION: return tr("Location"); case COLUMN_DATE_MODIFIED: return tr("Last Date Modified"); case COLUMN_SIZE: return tr("Size"); } return QVariant(); } case Qt::SizeHintRole: { return 128; } case Qt::TextAlignmentRole: { return QVariant(Qt::AlignLeft); } } return QVariant(); } int FileSystemModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent) return 5; }
-
-
What's the benefit of FileSystemModel::getFileInfo()? I would guess your this pointer is a nullptr