Deleting directory structure



  • I have the following directory structure.
    C:\aa\aa1
    C:\aa\aa2
    When I excuted the following snippet without using QFileSystemModel/QTreeView,
    it works as expected, it completely removes C:\aa and its two subdirectories.
    But when I use QFileSystemModel/QTreeView to navigate directories, it did
    not work properly.
    For example, if I navigate aa1 and aa2 then come back to
    C:\aa and excute
    DownDir_RM("C:\aa");
    all files under aa, aa1 and aa2 are gone, but the directory structures still
    there on TreeView and gives me a following message
    QFileSystemWatcher: FindNextChangeNotification failed!! (Access is denied.)
    and I cannot access C:\aa by explorer when the program is running.
    Then if I quit the program, C:\aa disappear from explorer.
    Does anyone have a similar experience?
    I know there is QDir::removeRecursive() in Qt5 but one of my project is based
    on Qt4.

    bool MainWindow::qt_unlink(QString fullFileName)
     {
         QFile f( fullFileName );
         QFileInfo qfi(fullFileName);
         if ( qfi.isFile() ) {
            if (f.remove()) {
             return true;
            }
         }
     return false;
     }
    
     void MainWindow::DownDir_RM(const QString d)
     {
        QDir dir(d);
       // SqlLog("order to delete dir:"+d+" ");
        qDebug()<<"order to delete dir:"<<d;
        if (dir.exists())
        {
            const QFileInfoList list =  dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst);;
            QFileInfo fi;
            for (int l = 0; l < list.size(); l++)
            {
                fi = list.at(l);
                if (fi.isDir() && fi.fileName() != "." && fi.fileName() != "..")
                    DownDir_RM(fi.absoluteFilePath());
                else if (fi.isFile())
                {
                    bool ret = qt_unlink(fi.absoluteFilePath());
                    if (!ret)
                        qDebug()<<"Can't remove:"<<fi.absoluteFilePath()<<"(write-protect?)";
                    //SqlLog("Can't remove: " + fi.absoluteFilePath() + " (write-protect?)");
                }
            }
            dir.rmdir(d);
        }
     }
    

  • Moderators

    @samdol

    I have added code wraps to your post.
    Please use in the future for improved reading of code snippets. Easiest you use the right button above of your edit window to add them.
    You may add also ``` manually before and after the code snippet, but apparently with some keyboards these markers are cumbersome to type.

    I have never worked with QFileSystemModel. Hwoever, while reading your post I was wondering if it has something with the specific place of the directoy to start?
    In your example the "aa" is on top level. Would you have the same problems when your structure starts in "c:\foo\aa" with all the subdirs.

    Note dir.entryInfoList(QDir::NoDotAndDotDot should already exclude the virtual folers "." and ".." from your list. Therefore the check later is not really required.



  • @koahnig
    Thank you for your point.
    Here is the link to my full snippets
    I have tested to put my aa under another folder, but still has the same problem. It works well under linux, but it does not work as expected under windows7.

    #include "MainWindow.h"
    
    MainWindow::MainWindow(QWidget *parent)	: QMainWindow(parent)
    {
        setupUi(this);
        treeModel = new QFileSystemModel(this);
        treeModel->setRootPath("");
        treeView = new QTreeView(this);
        treeView->setModel(treeModel);
        QModelIndex modelIndex = treeModel->setRootPath(treeModel->myComputer().toString());
        treeView->setRootIndex(modelIndex);
        setCentralWidget(treeView);
    
        QShortcut* shortcut_removeDir = new QShortcut(QKeySequence(Qt::Key_R), this);
        connect(shortcut_removeDir, SIGNAL(activated()), this, SLOT(removeDirClicked()));
    }
    
    bool MainWindow::qt_unlink(QString fullFileName)
     {
         QFile f( fullFileName );
         QFileInfo qfi(fullFileName);
         if ( qfi.isFile() ) {
            if (f.remove()) {
             return true;
            }
         }
     return false;
     }
    
     void MainWindow::DownDir_RM(const QString d)
     {
        QDir dir(d);
       // SqlLog("order to delete dir:"+d+" ");
       // qDebug()<<"order to delete dir:"<<d;
        if (dir.exists())
        {
            const QFileInfoList list =  dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst);;
            QFileInfo fi;
            for (int l = 0; l < list.size(); l++)
            {
                fi = list.at(l);
                if (fi.isDir())
                    DownDir_RM(fi.absoluteFilePath());
                else if (fi.isFile())
                {
                    bool ret = qt_unlink(fi.absoluteFilePath());
                    if (!ret)
                        qDebug()<<"Can't remove:"<<fi.absoluteFilePath()<<"(write-protect?)";
                    //SqlLog("Can't remove: " + fi.absoluteFilePath() + " (write-protect?)");
                }
            }
            dir.rmdir(d);
        }
     }
    
    
    
    void MainWindow::removeDirClicked()
    {
        qDebug()<<"removeDirClicked()";
        DownDir_RM(treeModel->fileInfo(treeView->currentIndex()).absoluteFilePath());
    }
    

    And header file is

    #ifndef MainWindow_H
    #define MainWindow_H
    
    #include <QtGlobal>
    #if QT_VERSION >= 0x050000
    #include <QtWidgets>
    #else
    #include <QtGui>
    #endif
    
    
    #include "ui_MainWindow.h"
    
    class MainWindow : public QMainWindow, private Ui::MainWindow
    {
        Q_OBJECT
    private:
        QFileSystemModel *treeModel;
        QTreeView *treeView;
    
    public:
        MainWindow(QWidget *parent=0);
        ~MainWindow(){}
        bool qt_unlink(QString fullFileName);
        void DownDir_RM(const QString d);
    
    public slots:
        void removeDirClicked();
    
    };
    
    #endif
    

  • Moderators

    @samdol

    As already indicated I never worked with QFileSystemModel. When looking your code I have noticed this:

    treeModel->setRootPath("");
    

    I am not sure if this is healthy. The docs do not give any hints on it, but there you are installing a system file watcher. For a starter I would place there a real root path (e.g. "c:\" or something like http://doc.qt.io/qt-5/qdir.html#rootPath ) .



  • @koahnig
    I made
    treeModel->setRootPath("C:/");
    but that did not make any change.
    I am starting thinking this maybe a bug.


  • Moderators

    @samdol

    You can check for a bug report on JIRA and eventually file a bug report, if you think it might be.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.