Using QFileSystemModel, QTreeView, and QSortFilterProxyModel
-
@Zbigniew-Sch said in Using QFileSystemModel, QTreeView, and QSortFilterProxyModel:
Sorry, but you didn't read the question. It's about the following: renaming a directory and
deleting a file from that directory, but the file item isn't being deleted from QTreeView.Yes, I did read the question. The MWE I posted behaves as I expect, given an out-of-process directory renaming and file deletion.
There may be a bug. Without a program to examine, it's unclear whether it is likely to lie in the OS, library, application code, or understanding of how each behaves.
@jeremy_k said in Using QFileSystemModel, QTreeView, and QSortFilterProxyModel:
given an out-of-process directory renaming and file deletion
Oh, I had thought it more likely OP was doing in-process operations via code on the
QTreeView! Shows how simple details matter :) -
@jeremy_k said in Using QFileSystemModel, QTreeView, and QSortFilterProxyModel:
given an out-of-process directory renaming and file deletion
Oh, I had thought it more likely OP was doing in-process operations via code on the
QTreeView! Shows how simple details matter :)@JonB said in Using QFileSystemModel, QTreeView, and QSortFilterProxyModel:
@jeremy_k said in Using QFileSystemModel, QTreeView, and QSortFilterProxyModel:
given an out-of-process directory renaming and file deletion
Oh, I had thought it more likely OP was doing in-process operations via code on the
QTreeView! Shows how simple details matter :)+1 on details mattering. I didn't see a point in guessing and complicating the code for an example of a MWE.
-
@JonB said in Using QFileSystemModel, QTreeView, and QSortFilterProxyModel:
@jeremy_k said in Using QFileSystemModel, QTreeView, and QSortFilterProxyModel:
given an out-of-process directory renaming and file deletion
Oh, I had thought it more likely OP was doing in-process operations via code on the
QTreeView! Shows how simple details matter :)+1 on details mattering. I didn't see a point in guessing and complicating the code for an example of a MWE.
@jeremy_k
OP is Windows, you are MacOS. I am Linux but not tested. May have to await a Windows user. If it's out-of-process it relies on theQFileSystemWatcherand the OS behaviour for notifications, that might or might not be relevant. If it's that area OP could debug-out to confirm the QFSW signals being emitted.If it's a fault in higher-level Qt logic instead we should be able to reproduce, but OP may have to confirm exactly what he does in outside world.
And if it is an issue only when there is a
QSortFilterProxyModelwe need to know whether OP has set any sorting or filtering on it. -
@jeremy_k
OP is Windows, you are MacOS. I am Linux but not tested. May have to await a Windows user. If it's out-of-process it relies on theQFileSystemWatcherand the OS behaviour for notifications, that might or might not be relevant. If it's that area OP could debug-out to confirm the QFSW signals being emitted.If it's a fault in higher-level Qt logic instead we should be able to reproduce, but OP may have to confirm exactly what he does in outside world.
And if it is an issue only when there is a
QSortFilterProxyModelwe need to know whether OP has set any sorting or filtering on it.@JonB said in Using QFileSystemModel, QTreeView, and QSortFilterProxyModel:
If it's out-of-process it relies on the
QFileSystemWatcherand the OS behaviour for notifications, that might or might not be relevant.This seems unlikely to be relevant. The original post says that connecting the file system model directly to the view does what is expected. I don't expect to find any file or operating system specific code in the proxy model.
-
I wrote a small program and I'm having the same problem.
This is definitely a bug in Qt, without QSortFilterProxyModel, everything works correctly.
I renamed the directory in my program and deleted a file from that directory
using Windows Explorer – it works correctly now. I'm out of ideas. -
The general advice from this thread remains valid:
- The existence of a test program doesn't help confirm or deny if nobody else can see the program.
- Bug reports can be filed at https://bugreports.qt.io/. Chances are high that whoever responds will also ask for a demonstrator.
-
The general advice from this thread remains valid:
- The existence of a test program doesn't help confirm or deny if nobody else can see the program.
- Bug reports can be filed at https://bugreports.qt.io/. Chances are high that whoever responds will also ask for a demonstrator.
@jeremy_k said in Using QFileSystemModel, QTreeView, and QSortFilterProxyModel:
Chances are high that whoever responds will also ask for a demonstrator.
Higher than high - otherwise it will be closed sooner or later with 'Needs more information'
-
How can I upload an entire example project as a ZIP file?
-
How can I upload an entire example project as a ZIP file?
@Zbigniew-Sch
People don't like looking at external and zip files. The forum does not offer this. We don't need a project for this issue.People are expecting a minimal reproducible example. Like a hundred lines. Stripped of anything and everything not required to show the behaviour, which you spend time doing. You have @jeremy_k's starting point code earlier in 20-odd lines. How much do you need to add to that to show it goes wrong for you?
-
Here is my example program to reproduce the problem:
Header of QMainWindow:
class LZImageViewerTest : public QMainWindow { Q_OBJECT public: LZImageViewerTest(QWidget *parent = nullptr); ~LZImageViewerTest(); QLZFileSystemModel *pcoGetFileSystemModel() { return m_pcoFileSystemModel; }; QSortFilterProxyModel *pcoSortFilterProxyModel() { return m_pcoSortFilterProxyModel;} static LZImageViewerTest* pcoGetMainWindow() { return m_stMainWindow; } static LZImageViewerTest* m_stMainWindow; private: Ui::LZImageViewerTestClass ui; QModelIndex m_coRootModelIndex; QLZTreeView *m_pcoTreeView; QHBoxLayout *m_pcoMainLayout; QLZMainWidget *m_pcoMainWidget; QLZFileSystemModel *m_pcoFileSystemModel; QSortFilterProxyModel *m_pcoSortFilterProxyModel; };QMainWindow cpp file:
LZImageViewerTest *LZImageViewerTest::m_stMainWindow = nullptr; LZImageViewerTest::LZImageViewerTest(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); m_stMainWindow = this; QScreen* pcoScreen = QGuiApplication::primaryScreen(); QRect coScreenGeometry = pcoScreen->geometry(); resize(QSize(coScreenGeometry.width() - 1400, coScreenGeometry.height() - 600)); // Center main window QRect mainFrameViewRect = frameGeometry(); QPoint centerPoint = screen()->availableGeometry().center(); mainFrameViewRect.moveCenter(centerPoint); move(mainFrameViewRect.topLeft()); m_pcoTreeView = new QLZTreeView(); m_pcoFileSystemModel = new QLZFileSystemModel(); m_coRootModelIndex= m_pcoFileSystemModel->setRootPath("D:\\Test"); m_pcoSortFilterProxyModel = new QSortFilterProxyModel(); m_pcoSortFilterProxyModel->setSourceModel(m_pcoFileSystemModel); m_pcoSortFilterProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_pcoSortFilterProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); m_pcoTreeView->setModel(m_pcoSortFilterProxyModel); m_pcoTreeView->setRootIndex(m_pcoSortFilterProxyModel->mapFromSource(m_coRootModelIndex)); m_pcoMainWidget = new QLZMainWidget(this); m_pcoMainWidget->setContentsMargins(3, 4, 4, 4); m_pcoMainLayout = new QHBoxLayout(this); m_pcoMainLayout->addWidget(m_pcoTreeView); m_pcoMainWidget->setLayout(m_pcoMainLayout); setCentralWidget(m_pcoMainWidget); } LZImageViewerTest::~LZImageViewer {}QLZFileSystemModel cpp file:
QLZFileSystemModel::QLZFileSystemModel(QObject* parent) : QFileSystemModel(parent) { } Qt::ItemFlags QLZFileSystemModel::flags(const QModelIndex& index) const { Qt::ItemFlags flags = QFileSystemModel::flags(index); flags |= Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; return flags; } QLZFileSystemModel::~QLZFileSystemModel() { }QLZTreeView cpp file:
QLZTreeView::QLZTreeView(QWidget* parent): QTreeView(parent) { setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &QWidget::customContextMenuRequested, this, &QLZTreeView::customContextMenu); } QLZTreeView::~QLZTreeView() { } void QLZTreeView::customContextMenu(const QPoint& point) { QMenu coContextMenu; QModelIndex coCurrentIndex = currentIndex(); if (!coCurrentIndex.isValid()) return; QAction* pcoRenameObjectsAction = coContextMenu.addAction(tr("Rename")); connect(pcoRenameObjectsAction, &QAction::triggered, this, [this, coCurrentIndex] { renameCurrentObject(coCurrentIndex); }); QAction* pcoDeleteObjectsAction = coContextMenu.addAction(tr("Delete")); connect(pcoDeleteObjectsAction, &QAction::triggered, this, [this, coCurrentIndex] { deleteCurrentObject(coCurrentIndex); }); coContextMenu.exec(viewport()->mapToGlobal(point)); QList<QAction*> coActionsList = coContextMenu.actions(); foreach(QAction * pcoAction, coActionsList) delete pcoAction; } void QLZTreeView::renameCurrentObject(QModelIndex coCurrentIndex) { if (!coCurrentIndex.isValid()) return; int iCurrentRow = coCurrentIndex.column(); if (iCurrentRow != 0) return; edit(currentIndex()); QList<QLineEdit*> coEditorList = findChildren<QLineEdit*>(); if (coEditorList.size() == 0) return; coEditorList[0]->installEventFilter(this); coEditorList[0]->setAlignment(Qt::AlignCenter); } void QLZTreeView::closeEditor(QWidget* coEditor, QAbstractItemDelegate::EndEditHint hint) { QSortFilterProxyModel* pcoSortFilterProxyModel = LZImageViewerTest::pcoGetMainWindow()->pcoSortFilterProxyModel(); pcoSortFilterProxyModel->invalidate(); QTreeView::closeEditor(coEditor, hint); } void QLZTreeView::deleteCurrentObject(QModelIndex coCurrentIndex) { if (!coCurrentIndex.isValid()) return; int iCurrentRow = coCurrentIndex.column(); if (iCurrentRow != 0) return; QList<QString> coSelectedIndexesPathList; QModelIndexList coIndexesList = selectedIndexes(); QFileSystemModel *pcoFileSystemModel = LZImageViewerTest::pcoGetMainWindow()->pcoGetFileSystemModel(); QSortFilterProxyModel *pcoSortFilterProxyModel = LZImageViewerTest::pcoGetMainWindow()->pcoSortFilterProxyModel(); for (int i = 0; i < coIndexesList.size(); i++) { if (coIndexesList[i].column() == 0) { // Delete file using "QFile::moveToTrash()" //QString coSelectedObjectPath = pcoFileSystemModel->filePath(pcoSortFilterProxyModel->mapToSource(coIndexesList[i])); //bool bRes = QFile::moveToTrash(coSelectedObjectPath); // Delete file using "pcoFileSystemModel->remove()" bool bRes = pcoFileSystemModel->remove(pcoSortFilterProxyModel->mapToSource(coIndexesList[i])); pcoSortFilterProxyModel->invalidate(); } } } -
This is to much. No need for an ui file , no context menu stuff and other stuff.
-
Sorry, I don't understand you. This is a minimal example to reproduce the problem.
If I completely reduce the source code, you won't see the dependencies and you won't be able to reproduce the problem. -
If you can't provide a real mre then I am out, sorry.
-
Does nobody have any suggestions as to what the error could be, or is this actually a Qt bug?
-
I'm using Windows 11 and Qt 6.10. I think this is a bug, or does anyone have a solution?
I've tried various changes, but it doesn't work.@Zbigniew-Sch said in Using QFileSystemModel, QTreeView, and QSortFilterProxyModel:
I'm using Windows 11 and Qt 6.10. I think this is a bug, or does anyone have a solution?
Is there any chance what you are seeing using 6.10 turns out to be caused by https://forum.qt.io/topic/164009/qsortfilterproxy-sorting-works-on-linux-but-fails-on-windows/6 and https://qt-project.atlassian.net/browse/QTBUG-141830 ? But I think that only occurs when using a static build? Yours isn't a static build is it?
-
I am using Qt 6.10.1 under Windows 11
Static build - NO -
Sorry, I don't understand you. This is a minimal example to reproduce the problem.
If I completely reduce the source code, you won't see the dependencies and you won't be able to reproduce the problem.@Zbigniew-Sch said in Using QFileSystemModel, QTreeView, and QSortFilterProxyModel:
Sorry, I don't understand you. This is a minimal example to reproduce the problem.
If I completely reduce the source code, you won't see the dependencies and you won't be able to reproduce the problem.This is not a minimal reproducible example.
Reduce it until there's only what is needed to reproduce the issue and nothing more.
It is also not usable for us because we can't run it.
Ideally it should be a self contained main.cpp with a couple of embedded classes if needed.No UI, just a QTreeView, a QSortFilterProxyModel and your model class.
Doing that will not only help us helping you but will also allow you to isolate the issue and most of the time figure out what it is and solve it by yourself.
This is most likely not a Qt bug but something coming from your code.
-
- QLZTreeView - see above
Header:
class QLZTreeView : public QTreeView { Q_OBJECT public: explicit QLZTreeView(QWidget* parent = nullptr); ~QLZTreeView(); protected: void renameCurrentObject(QModelIndex coCurrentIndex); void deleteCurrentObject(QModelIndex coCurrentIndex); void closeEditor(QWidget* editor, QAbstractItemDelegate::EndEditHint hint) override; private slots: void customContextMenu(const QPoint& point); };- QSortFilterProxyModel - is standard Qt class
- QLZFileSystemModel - see above
Header:class QLZFileSystemModel : public QFileSystemModel { Q_OBJECT public: explicit QLZFileSystemModel(QObject* parent = nullptr); ~QLZFileSystemModel(); protected: Qt::ItemFlags flags(const QModelIndex& index) const override;
};
- main.cpp - and that's all.
int main(int argc, char *argv[]) { QApplication app(argc, argv); LZImageViewerTest window; window.show(); return app.exec(); } - QLZTreeView - see above
-
Z Zbigniew-Sch has marked this topic as solved