beginResetModel/endResetModel problems
-
I want to reset my data, but when I use beginResetModel/endResetModel, the program just cracks. I don't know why.
I'm using Qt Quick's GridView to show the model.
I subclassed QAbstractListModel, which accomplish a function reading the picture file information in the the file system.
When I need to change the dir, I need to reset the model data dramatically, so I use beginResetModel/endResetModel, as following:
beginResetModel();
m_picfiles->clear(); //private data m_picfiles definition: QList<PhotoInfo> *m_picfiles;
changePicPath_Internal(m_path); //change m_picfiles
endResetModel();
the program will crack when calling endResetModel(), the error warning is:
ASSERT failure in QList<T>::at: "index out of range", file E:/QT/5.12.9/mingw73_64/include/QtCore/qlist.h, line 544Even I just use beginResetModel() and endResetModel(), the problem doesn't disappear.
And likely, there is the the same problem with beginRemoveRows/endRemoveRows
bool PhotoFiles::removeRows(int row, int count, const QModelIndex &/parent/)
{
if(row > rowCount())
return true;
beginRemoveRows(QModelIndex(), row, row+count-1);
for (int i = 0; i < count; ++i) {
m_picfiles->removeAt(row);
}
endRemoveRows();
return true;
}Although, I can use something like QFileSystemModel/FolderListModel, I really want to figure out the model subclass problem.
-
@ailika Please provide stack trace after the crash.
And please format your code properly - this helps others to read it. -
@ailika said in beginResetModel/endResetModel problems:
I'm sorry I don't know how to paste beautifully
Simply use the code tags.
And you did not post the stack trace after the crash... -
@ailika said in beginResetModel/endResetModel problems:
I'm sorry I don't know how to paste beautifully
Simply use the code tags.
And you did not post the stack trace after the crash...@jsulm
Thank you.#ifndef PHOTOFILES_H #define PHOTOFILES_H #include <QObject> #include <QAbstractListModel> #include <QFileInfo> #include <QUrl> #include <QDebug> class PhotoInfo{ public: PhotoInfo() {} PhotoInfo(QUrl url,QString title,bool isdir,QString path){m_url = url;m_title = title;m_isDir = isdir;m_path = path;} void setData(QUrl url,QString title,bool isdir,QString path){m_url = url;m_title = title;m_isDir = isdir;m_path = path;} void setIsDir(bool isdir) {m_isDir = isdir;} void setTitle(QString title){m_title = title;} void setUrl(QUrl url){m_url = url;} void setPath(QString path){m_path = path;} bool getIsDir(){return m_isDir;} QUrl getUrl(){return m_url;} QString getTitle(){return m_title;} QString getPath(){return m_path;} private: QUrl m_url; QString m_title; bool m_isDir; QString m_path; }; class PhotoFiles : public QAbstractListModel//QAbstractListModel { Q_OBJECT Q_ENUMS(FileRoles) Q_PROPERTY(QString folder READ folder WRITE setFolder NOTIFY folderChanged) public: enum FileRoles { FileNameRole = Qt::UserRole + 1, FileUrlRole, FileIsDirRole, }; void setFolder(const QString &a) { if (a != m_path) { m_path = a; changePicPath(m_path); emit folderChanged(); //emit the signal when the property value changes } } QString folder() const { return m_path; } PhotoFiles(); ~PhotoFiles(){delete m_picfiles;} QHash<int, QByteArray> roleNames() const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; //QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; //自定义函数 void changePicPath_Internal(QString paths); void changePicPath(QString paths); Q_INVOKABLE bool isFolder(int index); Q_INVOKABLE QString getPath(int index); Q_INVOKABLE void changePathAct(); signals: void folderChanged(); private: QList<PhotoInfo> *m_picfiles; QString m_path; }; #endif // PHOTOFILES_H #include "photos\photofiles.h" #include <QDir> #include <QDirIterator> #include <QDebug> PhotoFiles::PhotoFiles() { m_picfiles = new QList<PhotoInfo>; } QHash<int, QByteArray> PhotoFiles::roleNames() const { QHash<int, QByteArray> names; names[FileNameRole] = "fileName"; names[FileUrlRole] = "fileURL"; names[FileIsDirRole] = "fileIsDir"; return names; } int PhotoFiles::rowCount(const QModelIndex &/*parent*/) const { return m_picfiles->count(); } //QVariant PhotoFiles::headerData(int /*section*/, Qt::Orientation /*orientation*/, int /*role*/) const //{ // return QVariant(); //} QVariant PhotoFiles::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (index.row() >= m_picfiles->count()) return QVariant(); PhotoInfo photo = m_picfiles->at(index.row()); if (role == FileNameRole) return photo.getTitle(); else if(role == FileUrlRole) return photo.getUrl(); else if(role == FileIsDirRole) return photo.getIsDir(); else return QVariant(); return QVariant(); } Qt::ItemFlags PhotoFiles::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::ItemIsEnabled; return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; } bool PhotoFiles::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.isValid()) { PhotoInfo photo = m_picfiles->at(index.row()); if(role == FileNameRole) { photo.setTitle(value.toString()); } else if(role == FileUrlRole) { photo.setUrl(value.toUrl()); } else if(role == FileIsDirRole) { photo.setIsDir(value.toBool()); } else return false; emit dataChanged(index, index, {role}); return true; } return false; } bool PhotoFiles::insertRows(int row, int count, const QModelIndex &/*parent*/) { beginInsertRows(QModelIndex(), row, row+count-1); for (int i = 0; i < count; ++i) { m_picfiles->insert(row,PhotoInfo()); } endInsertRows(); return true; } bool PhotoFiles::removeRows(int row, int count, const QModelIndex &/*parent*/) { if(row > rowCount()) return true; beginRemoveRows(QModelIndex(), row, row+count-1); for (int i = 0; i < count; ++i) { m_picfiles->removeAt(row); } endRemoveRows(); return true; } //更换目录显示 void PhotoFiles::changePicPath_Internal(QString paths) { /*加入paths中所有的文件,包括文件夹(文件夹在前,图片在后,但是QDirIterator又没有排序信息,自己手动? TobedoneSign)*/ QStringList filter; filter << "*.jpg" << "*.png"; QDirIterator it(paths,filter,QDir::AllDirs|QDir::Files|QDir::NoSymLinks); while (it.hasNext()) { it.next(); if(it.fileName() != ".") //加入到m_picfiles种 { PhotoInfo photo; if(it.fileName() == "..") { photo.setIsDir(true); photo.setTitle("上级目录"); photo.setPath(it.filePath()+"/"); } else { QUrl url = QUrl::fromLocalFile(it.filePath()); photo.setData(url,it.fileName(),it.fileInfo().isDir(),it.filePath()+"/"); } m_picfiles->append(photo); } } //debug // QList<PhotoInfo>::iterator i; // for (i = m_picfiles->begin(); i != m_picfiles->end(); ++i) // { // qDebug() << i->getIsDir() << " " << i->getTitle() << " " << i->getUrl() << " " << i->getPath(); // } } void PhotoFiles::changePicPath(QString paths) { /*判断路径有效性*/ QDir directory(paths); if(!directory.exists()) { qDebug() << "path not exist!"; return; } m_path = paths; //delete m_picfiles; //m_picfiles = new QList<PhotoInfo>; beginResetModel(); m_picfiles->clear(); changePicPath_Internal(m_path); endResetModel(); } void PhotoFiles::changePathAct() { beginResetModel(); m_picfiles->clear(); changePicPath_Internal(m_path); endResetModel(); } bool PhotoFiles::isFolder(int index) { PhotoInfo photo = m_picfiles->at(index); return photo.getIsDir(); } QString PhotoFiles::getPath(int index) { PhotoInfo photo = m_picfiles->at(index); return photo.getPath(); } import QtQuick 2.12 import QtQuick.Window 2.12 import PhotoFiles 1.0 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 Item { id:root property string pic_folder//:"E:/BaiduNetdiskDownload/qt_projects/ZjrDesktop/build-ZjrDesktop-Desktop_Qt_5_12_9_MinGW_64_bit-Debug/debug/images/" //初始化时,这个是空,后来才赋值的;所以model里面没处理好的话,不会更新显示 GridView { id:grid width: parent.width; height: parent.height cellWidth: 150; cellHeight: 150 cacheBuffer:800 //没看出来有什么区别 PhotoFiles { id: folderModel folder:pic_folder } model: folderModel delegate: fileDelegate ScrollBar.vertical: ScrollBar {} } Component { id: fileDelegate Item{ id:delegate_item width: grid.cellWidth height: grid.cellHeight Column{ anchors.fill: parent Image { visible: true height:delegate_item.GridView.view.model.isFolder(index)?delegate_item.height-folder_text.implicitHeight:delegate_item.height width:delegate_item.width source:delegate_item.GridView.view.model.isFolder(index)?"qrc:///photos/images/filefolder_pic.png":fileURL mipmap:true //但是没有系统缩略图效果好 } Text { anchors.horizontalCenter: parent.horizontalCenter id:folder_text text: fileName visible: delegate_item.GridView.view.model.isFolder(index) font.pixelSize: 16 } } MouseArea{ anchors.fill: parent onClicked:{ if(delegate_item.GridView.view.model.isFolder(index)) { root.pic_folder = delegate_item.GridView.view.model.getPath(index) } else { //stack.push(photo_disp,{"start_pic": index}) } } } } } }
-
@jsulm
Thank you.#ifndef PHOTOFILES_H #define PHOTOFILES_H #include <QObject> #include <QAbstractListModel> #include <QFileInfo> #include <QUrl> #include <QDebug> class PhotoInfo{ public: PhotoInfo() {} PhotoInfo(QUrl url,QString title,bool isdir,QString path){m_url = url;m_title = title;m_isDir = isdir;m_path = path;} void setData(QUrl url,QString title,bool isdir,QString path){m_url = url;m_title = title;m_isDir = isdir;m_path = path;} void setIsDir(bool isdir) {m_isDir = isdir;} void setTitle(QString title){m_title = title;} void setUrl(QUrl url){m_url = url;} void setPath(QString path){m_path = path;} bool getIsDir(){return m_isDir;} QUrl getUrl(){return m_url;} QString getTitle(){return m_title;} QString getPath(){return m_path;} private: QUrl m_url; QString m_title; bool m_isDir; QString m_path; }; class PhotoFiles : public QAbstractListModel//QAbstractListModel { Q_OBJECT Q_ENUMS(FileRoles) Q_PROPERTY(QString folder READ folder WRITE setFolder NOTIFY folderChanged) public: enum FileRoles { FileNameRole = Qt::UserRole + 1, FileUrlRole, FileIsDirRole, }; void setFolder(const QString &a) { if (a != m_path) { m_path = a; changePicPath(m_path); emit folderChanged(); //emit the signal when the property value changes } } QString folder() const { return m_path; } PhotoFiles(); ~PhotoFiles(){delete m_picfiles;} QHash<int, QByteArray> roleNames() const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; //QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; //自定义函数 void changePicPath_Internal(QString paths); void changePicPath(QString paths); Q_INVOKABLE bool isFolder(int index); Q_INVOKABLE QString getPath(int index); Q_INVOKABLE void changePathAct(); signals: void folderChanged(); private: QList<PhotoInfo> *m_picfiles; QString m_path; }; #endif // PHOTOFILES_H #include "photos\photofiles.h" #include <QDir> #include <QDirIterator> #include <QDebug> PhotoFiles::PhotoFiles() { m_picfiles = new QList<PhotoInfo>; } QHash<int, QByteArray> PhotoFiles::roleNames() const { QHash<int, QByteArray> names; names[FileNameRole] = "fileName"; names[FileUrlRole] = "fileURL"; names[FileIsDirRole] = "fileIsDir"; return names; } int PhotoFiles::rowCount(const QModelIndex &/*parent*/) const { return m_picfiles->count(); } //QVariant PhotoFiles::headerData(int /*section*/, Qt::Orientation /*orientation*/, int /*role*/) const //{ // return QVariant(); //} QVariant PhotoFiles::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (index.row() >= m_picfiles->count()) return QVariant(); PhotoInfo photo = m_picfiles->at(index.row()); if (role == FileNameRole) return photo.getTitle(); else if(role == FileUrlRole) return photo.getUrl(); else if(role == FileIsDirRole) return photo.getIsDir(); else return QVariant(); return QVariant(); } Qt::ItemFlags PhotoFiles::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::ItemIsEnabled; return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; } bool PhotoFiles::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.isValid()) { PhotoInfo photo = m_picfiles->at(index.row()); if(role == FileNameRole) { photo.setTitle(value.toString()); } else if(role == FileUrlRole) { photo.setUrl(value.toUrl()); } else if(role == FileIsDirRole) { photo.setIsDir(value.toBool()); } else return false; emit dataChanged(index, index, {role}); return true; } return false; } bool PhotoFiles::insertRows(int row, int count, const QModelIndex &/*parent*/) { beginInsertRows(QModelIndex(), row, row+count-1); for (int i = 0; i < count; ++i) { m_picfiles->insert(row,PhotoInfo()); } endInsertRows(); return true; } bool PhotoFiles::removeRows(int row, int count, const QModelIndex &/*parent*/) { if(row > rowCount()) return true; beginRemoveRows(QModelIndex(), row, row+count-1); for (int i = 0; i < count; ++i) { m_picfiles->removeAt(row); } endRemoveRows(); return true; } //更换目录显示 void PhotoFiles::changePicPath_Internal(QString paths) { /*加入paths中所有的文件,包括文件夹(文件夹在前,图片在后,但是QDirIterator又没有排序信息,自己手动? TobedoneSign)*/ QStringList filter; filter << "*.jpg" << "*.png"; QDirIterator it(paths,filter,QDir::AllDirs|QDir::Files|QDir::NoSymLinks); while (it.hasNext()) { it.next(); if(it.fileName() != ".") //加入到m_picfiles种 { PhotoInfo photo; if(it.fileName() == "..") { photo.setIsDir(true); photo.setTitle("上级目录"); photo.setPath(it.filePath()+"/"); } else { QUrl url = QUrl::fromLocalFile(it.filePath()); photo.setData(url,it.fileName(),it.fileInfo().isDir(),it.filePath()+"/"); } m_picfiles->append(photo); } } //debug // QList<PhotoInfo>::iterator i; // for (i = m_picfiles->begin(); i != m_picfiles->end(); ++i) // { // qDebug() << i->getIsDir() << " " << i->getTitle() << " " << i->getUrl() << " " << i->getPath(); // } } void PhotoFiles::changePicPath(QString paths) { /*判断路径有效性*/ QDir directory(paths); if(!directory.exists()) { qDebug() << "path not exist!"; return; } m_path = paths; //delete m_picfiles; //m_picfiles = new QList<PhotoInfo>; beginResetModel(); m_picfiles->clear(); changePicPath_Internal(m_path); endResetModel(); } void PhotoFiles::changePathAct() { beginResetModel(); m_picfiles->clear(); changePicPath_Internal(m_path); endResetModel(); } bool PhotoFiles::isFolder(int index) { PhotoInfo photo = m_picfiles->at(index); return photo.getIsDir(); } QString PhotoFiles::getPath(int index) { PhotoInfo photo = m_picfiles->at(index); return photo.getPath(); } import QtQuick 2.12 import QtQuick.Window 2.12 import PhotoFiles 1.0 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 Item { id:root property string pic_folder//:"E:/BaiduNetdiskDownload/qt_projects/ZjrDesktop/build-ZjrDesktop-Desktop_Qt_5_12_9_MinGW_64_bit-Debug/debug/images/" //初始化时,这个是空,后来才赋值的;所以model里面没处理好的话,不会更新显示 GridView { id:grid width: parent.width; height: parent.height cellWidth: 150; cellHeight: 150 cacheBuffer:800 //没看出来有什么区别 PhotoFiles { id: folderModel folder:pic_folder } model: folderModel delegate: fileDelegate ScrollBar.vertical: ScrollBar {} } Component { id: fileDelegate Item{ id:delegate_item width: grid.cellWidth height: grid.cellHeight Column{ anchors.fill: parent Image { visible: true height:delegate_item.GridView.view.model.isFolder(index)?delegate_item.height-folder_text.implicitHeight:delegate_item.height width:delegate_item.width source:delegate_item.GridView.view.model.isFolder(index)?"qrc:///photos/images/filefolder_pic.png":fileURL mipmap:true //但是没有系统缩略图效果好 } Text { anchors.horizontalCenter: parent.horizontalCenter id:folder_text text: fileName visible: delegate_item.GridView.view.model.isFolder(index) font.pixelSize: 16 } } MouseArea{ anchors.fill: parent onClicked:{ if(delegate_item.GridView.view.model.isFolder(index)) { root.pic_folder = delegate_item.GridView.view.model.getPath(index) } else { //stack.push(photo_disp,{"start_pic": index}) } } } } } }
@ailika said in beginResetModel/endResetModel problems:
bool PhotoFiles::isFolder(int index)
{
PhotoInfo photo = m_picfiles->at(index);
return photo.getIsDir();
}You're not checking whether "index" is out of bounds or not. And according to the error message it is...
-
@ailika said in beginResetModel/endResetModel problems:
bool PhotoFiles::isFolder(int index)
{
PhotoInfo photo = m_picfiles->at(index);
return photo.getIsDir();
}You're not checking whether "index" is out of bounds or not. And according to the error message it is...
@jsulm Thank you very much. It solves the problem. I just saw someone has a similar problem, but I neglected these last two functions. I thought these were not the inhereted functions so that it does's not matter. What a misunderstanding.
By the way, Did you figure out the reason by code or by the stack? How to check the stack? Is it like that I can find in what function the problem takes place? -
-
@jsulm Thank you very much. It solves the problem. I just saw someone has a similar problem, but I neglected these last two functions. I thought these were not the inhereted functions so that it does's not matter. What a misunderstanding.
By the way, Did you figure out the reason by code or by the stack? How to check the stack? Is it like that I can find in what function the problem takes place?@ailika said in beginResetModel/endResetModel problems:
Did you figure out the reason by code or by the stack?
Both. In the stack trace you can see that the last method from your code which was called is PhotoFiles::isFolder (line 6 in stack trace). So I checked the implementation of that method and saw that you do not check the index which also matches the error you posted.
-
@ailika said in beginResetModel/endResetModel problems:
Did you figure out the reason by code or by the stack?
Both. In the stack trace you can see that the last method from your code which was called is PhotoFiles::isFolder (line 6 in stack trace). So I checked the implementation of that method and saw that you do not check the index which also matches the error you posted.
@jsulm Oh, I see. I have never used the stack to check problems. It seems really helpful. I have thought some Qt inbuild functions somehow call my QList object because Qt has meta object functions....I thought I have wrongly used the model subclass process.
Thank you very much. -
@ailika said in beginResetModel/endResetModel problems:
Did you figure out the reason by code or by the stack?
Both. In the stack trace you can see that the last method from your code which was called is PhotoFiles::isFolder (line 6 in stack trace). So I checked the implementation of that method and saw that you do not check the index which also matches the error you posted.
@jsulm I have another question.
I add delete function in the program. the model's function changes as follows:bool PhotoFiles::removeRows(int row, int count, const QModelIndex &/*parent*/) { if(row > rowCount()) return true; beginRemoveRows(QModelIndex(), row, row+count-1); PhotoInfo photo = m_picfiles->at(row); QUrl url = photo.getUrl(); qDebug() << url; QFile file(url.toLocalFile()); for (int i = 0; i < count; ++i) { m_picfiles->removeAt(row); } if(file.exists()) { //qDebug() << "file exist"; if(file.remove()) { //qDebug() << "file removed"; return true; } else qDebug() << "file remove fail"; } endRemoveRows(); return true; }
And I use a button to delete the selected picture.
```Button {//删除文件 id: btnDelete anchors.left: parent.left anchors.leftMargin: 10 anchors.verticalCenter: parent.verticalCenter style: ButtonStyle { background: Image { sourceSize.width: 20 sourceSize.height: 20 anchors.fill: parent source: "qrc:/photos/images/delete.png" } } onClicked: { if(folderModel.isFolder(pathView.currentIndex) == true) //没有做目录删除处理 return; var del_index = pathView.currentIndex if(pathView.currentIndex == folderModel.rowCount()) pathView.currentIndex = pathView.currentIndex - 1 else pathView.currentIndex = pathView.currentIndex + 1 folderModel.removeRow(del_index) } }
Though after I delete a picture, it will show the next picture and the picture is deleted from the file system, when I slip back,the deleted picture is still shown(like it has some cache). How to solve this question? I see some example code that only says the only thing to do is to delete it between beginRemoveRows/endRemoveRows, but as I use this, the view seems not be able to be informed of the deleting operation.
-
@jsulm I have another question.
I add delete function in the program. the model's function changes as follows:bool PhotoFiles::removeRows(int row, int count, const QModelIndex &/*parent*/) { if(row > rowCount()) return true; beginRemoveRows(QModelIndex(), row, row+count-1); PhotoInfo photo = m_picfiles->at(row); QUrl url = photo.getUrl(); qDebug() << url; QFile file(url.toLocalFile()); for (int i = 0; i < count; ++i) { m_picfiles->removeAt(row); } if(file.exists()) { //qDebug() << "file exist"; if(file.remove()) { //qDebug() << "file removed"; return true; } else qDebug() << "file remove fail"; } endRemoveRows(); return true; }
And I use a button to delete the selected picture.
```Button {//删除文件 id: btnDelete anchors.left: parent.left anchors.leftMargin: 10 anchors.verticalCenter: parent.verticalCenter style: ButtonStyle { background: Image { sourceSize.width: 20 sourceSize.height: 20 anchors.fill: parent source: "qrc:/photos/images/delete.png" } } onClicked: { if(folderModel.isFolder(pathView.currentIndex) == true) //没有做目录删除处理 return; var del_index = pathView.currentIndex if(pathView.currentIndex == folderModel.rowCount()) pathView.currentIndex = pathView.currentIndex - 1 else pathView.currentIndex = pathView.currentIndex + 1 folderModel.removeRow(del_index) } }
Though after I delete a picture, it will show the next picture and the picture is deleted from the file system, when I slip back,the deleted picture is still shown(like it has some cache). How to solve this question? I see some example code that only says the only thing to do is to delete it between beginRemoveRows/endRemoveRows, but as I use this, the view seems not be able to be informed of the deleting operation.
@ailika said in beginResetModel/endResetModel problems:
endRemoveRows()
This is never called. Fix your loop.
-
@ailika said in beginResetModel/endResetModel problems:
endRemoveRows()
This is never called. Fix your loop.
@Christian-Ehrlicher What do you mean? I have called it at the end of the removeRows() function
The following is code segment from qt's help document[Model/View Programming], I think it is just like my code
-
@Christian-Ehrlicher What do you mean? I have called it at the end of the removeRows() function
The following is code segment from qt's help document[Model/View Programming], I think it is just like my code
@ailika said in beginResetModel/endResetModel problems:
, I think it is just like my code
But it is not. You return when you removed the first file (and forget to remove the rest btw, but that's just another error in your code)
-
@ailika said in beginResetModel/endResetModel problems:
endRemoveRows()
This is never called. Fix your loop.
-
@Christian-Ehrlicher Oh, right. How careless of me. I copyed the file deleting operation code and forget to delete the return true.
This is awkward.I thought there is some mechanisam that I don't know...
Thank you very much.