-
UID:202628
-
- 注册时间2020-05-17
- 最后登录2024-04-08
- 在线时间445小时
-
- 发帖395
- 搜Ta的帖子
- 精华0
- 金钱5770
- 威望436
- 贡献值0
- 好评度356
-
访问TA的空间加好友用道具
|
如题,用QFileSystemWatcher监控某个指定的 目录变化,若拷贝1000张 图片到该监控目录,则会出现QFileSystemWatcher对象一下子触发很多个同一信号,这个信号对应一个同一槽函数,槽函数主要处理该信号获取的图片 文件信息集合并发送给主 线程,开启子线程,将图片信息同步更新到 QTableView表格的模型上,具体代码如下: - //CustomTableView.h
- class CustomTableView : public QTableView
- {
- Q_OBJECT
- public:
- CustomTableView(QWidget *parent = nullptr);
- void addWatchPath(QString path);
-
- signals:
- void startUpdateDirectory(int type, QString diskPath, QList<FileInfo> recordList, QStringList curFileNameList, QString newFileName);
-
- private:
- QThread *m_fsThread;
- FSWatcherWorker *m_fsWorker; //继承QObject
- QFileSystemWatcher *m_fsWatcher;
- CustomTableModel *m_customTableModel; //自定义模型,继承QAbstractTableModel
- QMap<QString, QStringList> m_currentContentsMap; // 当前每个监控的内容目录列表
- QList<FileInfo> m_recordList; //监控目录的集合,FileInfo为监控目录下文件或文件夹的信息,例如名称、大小、修改时间等。
- };
- //CustomTableView.cpp
- CustomTableView::CustomTableView(QWidget *parent)
- :QTableView(parent)
- {this->addWatchPath("E:\\test\\");}
- void CustomTableView::addWatchPath(QString path)
- {
- m_fsWatcher = new QFileSystemWatcher();
- connect(m_fsWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(onDirectoryChanged(QString)));
- // 添加监控路径
- m_fsWatcher->addPath(path);
- // 如果添加路径是一个目录,保存当前内容列表
- QFileInfo file(path);
- if (file.isDir())
- {
- const QDir dirw(path);
- m_currentContentsMap[path] = dirw.entryList(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
- }
- m_fsThread = new QThread(this);
- if(m_fsWorker == NULL)
- {
- m_fsWorker = new FSWatcherWorker;
- m_fsWorker->moveToThread(m_fsThread);
- connect(m_fsThread, &QThread::finished, m_fsWorker, &FSWatcherWorker::deleteLater);
- connect(m_fsThread, &QThread::finished, this, &CustomTableView::setFsWorkerNull);
- connect(m_fsWorker, &FSWatcherWorker::updateDir, this, &CustomTableView::onUpdateDir);
- connect(this, &CustomTableView::startUpdateDirectory, m_fsWorker, &FSWatcherWorker::startFSWatcherWork);//startFSWatcherWork获取文件信息并发送更新集合
- connect(this, &CustomTableView::cancelUpdateDirectory, m_fsWorker, &FSWatcherWorker::cancelFSWatcherWork);
- m_fsThread->start();
- }
- }
- void dCustomTableView::onDirectoryChanged(QString path)
- {
- // 比较最新的内容和保存的内容找出区别(变化)
- QStringList currEntryList = m_currentContentsMap[path];
- const QDir dir(path);
- QStringList newEntryList = dir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
- QSet<QString> newDirSet = QSet<QString>::fromList(newEntryList);
- QSet<QString> currentDirSet = QSet<QString>::fromList(currEntryList);
- // 添加了文件
- QSet<QString> newFiles = newDirSet - currentDirSet;
- QStringList newFile = newFiles.toList();
- // 文件已被移除
- QSet<QString> deletedFiles = currentDirSet - newDirSet;
- QStringList deleteFile = deletedFiles.toList();
- // 更新当前设置
- m_currentContentsMap[path] = newEntryList;
- if (!newFile.isEmpty() && !deleteFile.isEmpty())
- {
- // 文件/目录重命名
- if ((newFile.count() == 1) && (deleteFile.count() == 1))
- {
- DEBUG_PRINT(FALSE, QString("directory updated: %1, File Renamed from %2 to %3").arg(path).arg(deleteFile.first()).arg(newFile.first()));
- emit startUpdateDirectory(0, m_watchPath, currEntryList, newEntryList);
- }
- }
- else
- {
- // 添加新文件/目录至Dir
- if (!newFile.isEmpty())
- {
- DEBUG_PRINT(FALSE, QString("directory updated: %1, New Files/Dirs added: %2").arg(path).arg(QString::number(newFile.size())));
- foreach (QString file, newFile)
- {
- // 处理操作每个新文件....
- if(!file.isEmpty())
- {
- emit startUpdateDirectory(1, m_watchPath, m_recordList, currEntryList, file);
- }
- }
- }
- // 从Dir中删除文件/目录
- if (!deleteFile.isEmpty())
- {
- DEBUG_PRINT(FALSE, QString("directory updated: %1, Files/Dirs deleted: %2").arg(path).arg(QString::number(deleteFile.size())));
- foreach(QString file, deleteFile)
- {
- // 处理操作每个被删除的文件....
- if(!file.isEmpty())
- {
- emit startUpdateDirectory(-1, m_watchPath, m_recordList, currEntryList,file);
- }
- }
-
- }
- }
- }
- void dCustomTableView::onUpdateDir2(int size, FileRecord record)
- {
- if(size > 0)
- {
- m_recordList.push_back(record);
- m_customTableModel->updateData(m_recordList); //此处更新模型数据,即具体updateData代码为{this->beginResetModel();m_recordList = recordList;this->endResetModel();}
- }
- if(size == 0)
- {
- m_recordList.clear();
- m_customTableModel->removeRows(0, m_customTableModel->rowCount());
- m_customTableModel->updateData(m_recordList);
- }
- }
如上代码,在运行过程中,拷贝1000个文件到指定监控目录下,主 界面从拷贝的那一刻开始到刷新QTableView表格上的模型的时间很卡,其中这段时间,将1000张照片完全拷贝完到监控目录大概时间40s到60s左右,而刷新QTableView模型就大概8分钟到10分钟左右,这个是测试的日志分析的。各位大佬们,你们有什么办法可以优化这个 问题吗?在线等,欢迎各位大佬们指点一二,小弟感激不尽。
|