class CustomSysmodel : public QFileSystemModel { Q_OBJECT public: CustomSysmodel(QWidget *parent = Q_NULLPTR) : QFileSystemModel(parent) , m_limit(100) , m_timer(new QTimer(this))//m_timer 使用 this 作为其父对象创建的,在 CustomSysmodel 对象被删除时自动删除(不确定) { connect(m_timer, &QTimer::timeout, this, &CustomSysmodel::loadMoreFiles);//直接在构造函数中植入计时器 m_timer->setInterval(2000); } void CustomSysmodel::fetchFiles(const QString &path) { emit started(); QThread *thread = new QThread; //**********************需要释放空间 FileSystemWorker *worker = new FileSystemWorker; worker->moveToThread(thread); connect(thread, &QThread::started, worker, [this, worker, path]() { worker->fetchFiles(path); }); connect(worker, &FileSystemWorker::fileFound, this, &CustomSysmodel::fileFound); connect(worker, &FileSystemWorker::finished, thread, &QThread::quit); connect(worker, &FileSystemWorker::finished, worker, &FileSystemWorker::deleteLater); connect(thread, &QThread::finished, thread, &QThread::deleteLater); connect(worker, &FileSystemWorker::finished, this, &CustomSysmodel::finished); thread->start();//启动线程 QMetaObject::invokeMethod(thread, "wait", Qt::QueuedConnection);//另一种写法,还是不能边构建model边描画 delete thread; delete worker; } } class FileSystemWorker : public QObject { Q_OBJECT public: FileSystemWorker(QObject *parent = nullptr) : QObject(parent) {} public slots: void fetchFiles(const QString &path) { QFileInfoList files = QDir(path).entryInfoList(QDir::Files); foreach (const QFileInfo &fileInfo, files) { cout<<"xianc"<<endl; emit fileFound(fileInfo.absoluteFilePath()); } } signals: void started(); void finished(); void fileFound(const QString &filePath); }; 如上述代码所示:qtreeview使用继承自Qfilesystemmodel的自定义模型,想要实现单独线程读取文件,再发送给主线程,目的是为了访问百万级文件时,可以流畅访问。 但现在只有全部加载完主线程才能运行,分析原因,给出改动较小的修改方案
时间: 2024-02-21 20:56:44 浏览: 80
问题已经收到了,我会根据您的要求回答问题。
针对您的代码,要实现单独线程读取文件,再发送给主线程,可以使用QFuture和QtConcurrent库来实现。具体实现步骤如下:
1. 在CustomSysmodel类中,添加一个私有成员变量QFutureWatcher<void> m_watcher,用于监视QFuture的状态。
2. 修改fetchFiles函数,使用QtConcurrent::run函数来创建一个新线程,并在该线程中执行读取文件的操作。将读取到的文件路径存储在一个QStringList中,并使用QFuture和QtConcurrent库的reduce函数将所有线程读取到的文件路径合并为一个QStringList。
3. 将合并后的QStringList发送给主线程处理。
修改后的CustomSysmodel类的代码如下:
```
class CustomSysmodel : public QFileSystemModel {
Q_OBJECT
public:
CustomSysmodel(QWidget *parent = Q_NULLPTR)
: QFileSystemModel(parent)
, m_limit(100)
, m_timer(new QTimer(this))
{
connect(m_timer, &QTimer::timeout, this, &CustomSysmodel::loadMoreFiles);
m_timer->setInterval(2000);
}
void fetchFiles(const QString &path) {
emit started();
QFutureWatcher<void> watcher;
connect(&watcher, &QFutureWatcher<void>::finished, this, [this, watcher]() {
QStringList filePaths = watcher.future().result();
foreach (const QString &filePath, filePaths) {
m_files.append(filePath);
if (m_files.count() >= m_limit) {
break;
}
}
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
emit finished();
});
QFuture<QStringList> future = QtConcurrent::mappedReduced(
QList<QString>({ path }),
[](const QString &path) {
QFileInfoList files = QDir(path).entryInfoList(QDir::Files);
QStringList filePaths;
foreach (const QFileInfo &fileInfo, files) {
filePaths.append(fileInfo.absoluteFilePath());
}
return filePaths;
},
[](const QStringList &list1, const QStringList &list2) {
QStringList result = list1;
result.append(list2);
return result;
}
);
watcher.setFuture(future);
}
private:
int m_limit;
QTimer *m_timer;
};
```
经过以上修改,即可实现分批加载文件,提高程序的响应速度。
阅读全文