由于Qt的体系过于庞大,即使是某个模块,分析起来也十分困难。对于QFileSystemModel,我们在这里对单个重要函数慢慢分析
1 /*!
\internal The thread has received new information about files,
update and emit dataChanged if it has actually changed.
*/
void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QVector<QPair<QString, QFileInfo> > &updates)
{
#ifndef QT_NO_FILESYSTEMWATCHER
Q_Q(QFileSystemModel);
QVector<QString> rowsToUpdate;
QStringList newFiles;
QFileSystemModelPrivate::QFileSystemNode *parentNode = node(path, false);
QModelIndex parentIndex = index(parentNode);
for (const auto &update : updates) {
QString fileName = update.first;
Q_ASSERT(!fileName.isEmpty());
QExtendedInformation info = fileInfoGatherer.getInfo(update.second);
bool previouslyHere = parentNode->children.contains(fileName);
if (!previouslyHere) {
addNode(parentNode, fileName, info.fileInfo());
}
QFileSystemModelPrivate::QFileSystemNode * node = parentNode->children.value(fileName);
bool isCaseSensitive = parentNode->caseSensitive();
if (isCaseSensitive) {
if (node->fileName != fileName)
continue;
} else {
if (QString::compare(node->fileName,fileName,Qt::CaseInsensitive) != )
continue;
}
if (isCaseSensitive) {
Q_ASSERT(node->fileName == fileName);
} else {
node->fileName = fileName;
} if (*node != info ) {
node->populate(info);
bypassFilters.remove(node);
// brand new information.
if (filtersAcceptsNode(node)) {
if (!node->isVisible) {
newFiles.append(fileName);
} else {
rowsToUpdate.append(fileName);
}
} else {
if (node->isVisible) {
int visibleLocation = parentNode->visibleLocation(fileName);
removeVisibleFile(parentNode, visibleLocation);
} else {
// The file is not visible, don't do anything
}
}
}
} // bundle up all of the changed signals into as few as possible.
std::sort(rowsToUpdate.begin(), rowsToUpdate.end());
QString min;
QString max;
for (int i = ; i < rowsToUpdate.count(); ++i) {
QString value = rowsToUpdate.at(i);
//##TODO is there a way to bundle signals with QString as the content of the list?
/*if (min.isEmpty()) {
min = value;
if (i != rowsToUpdate.count() - 1)
continue;
}
if (i != rowsToUpdate.count() - 1) {
if ((value == min + 1 && max.isEmpty()) || value == max + 1) {
max = value;
continue;
}
}*/
max = value;
min = value;
int visibleMin = parentNode->visibleLocation(min);
int visibleMax = parentNode->visibleLocation(max);
if (visibleMin >=
&& visibleMin < parentNode->visibleChildren.count()
&& parentNode->visibleChildren.at(visibleMin) == min
&& visibleMax >= ) {
QModelIndex bottom = q->index(translateVisibleLocation(parentNode, visibleMin), , parentIndex);
QModelIndex top = q->index(translateVisibleLocation(parentNode, visibleMax), , parentIndex);
emit q->dataChanged(bottom, top);
} /*min = QString();
max = QString();*/
} if (newFiles.count() > ) {
addVisibleFiles(parentNode, newFiles);
} if (newFiles.count() > || (sortColumn != && rowsToUpdate.count() > )) {
forceSort = true;
delayedSort();
}
#else
Q_UNUSED(path)
Q_UNUSED(updates)
#endif // !QT_NO_FILESYSTEMWATCHER
}

  针对程序,一一作出解释:Q_UNUSED宏,避免因为某个变量没有使用,而编译器报错:

 /*
Avoid "unused parameter" warnings
*/
#define Q_UNUSED(x) (void)x;

  接下来,解释下面这句,位于主代码18行的:

QExtendedInformation info = fileInfoGatherer.getInfo(update.second);

  找到它所在的头文件qfileinfogatherer_p.h

 #ifndef QFILEINFOGATHERER_H
#define QFILEINFOGATHERER_H //
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
// #include <QtWidgets/private/qtwidgetsglobal_p.h> #include <qthread.h>
#include <qmutex.h>
#include <qwaitcondition.h>
#include <qfilesystemwatcher.h>
#include <qfileiconprovider.h>
#include <qpair.h>
#include <qstack.h>
#include <qdatetime.h>
#include <qdir.h>
#include <qelapsedtimer.h> #include <private/qfilesystemengine_p.h> QT_REQUIRE_CONFIG(filesystemmodel); QT_BEGIN_NAMESPACE class QExtendedInformation {
public:
enum Type { Dir, File, System }; QExtendedInformation() {}
QExtendedInformation(const QFileInfo &info) : mFileInfo(info) {} inline bool isDir() { return type() == Dir; }
inline bool isFile() { return type() == File; }
inline bool isSystem() { return type() == System; } bool operator ==(const QExtendedInformation &fileInfo) const {
return mFileInfo == fileInfo.mFileInfo
&& displayType == fileInfo.displayType
&& permissions() == fileInfo.permissions();
} #ifndef QT_NO_FSFILEENGINE
bool isCaseSensitive() const {
return QFileSystemEngine::isCaseSensitive();
}
#endif QFile::Permissions permissions() const {
return mFileInfo.permissions();
} Type type() const {
if (mFileInfo.isDir()) {
return QExtendedInformation::Dir;
}
if (mFileInfo.isFile()) {
return QExtendedInformation::File;
}
if (!mFileInfo.exists() && mFileInfo.isSymLink()) {
return QExtendedInformation::System;
}
return QExtendedInformation::System;
} bool isSymLink(bool ignoreNtfsSymLinks = false) const
{
if (ignoreNtfsSymLinks) {
#ifdef Q_OS_WIN
return !mFileInfo.suffix().compare(QLatin1String("lnk"), Qt::CaseInsensitive);
#endif
}
return mFileInfo.isSymLink();
} bool isHidden() const {
return mFileInfo.isHidden();
} QFileInfo fileInfo() const {
return mFileInfo;
} QDateTime lastModified() const {
return mFileInfo.lastModified();
} qint64 size() const {
qint64 size = -;
if (type() == QExtendedInformation::Dir)
size = ;
if (type() == QExtendedInformation::File)
size = mFileInfo.size();
if (!mFileInfo.exists() && !mFileInfo.isSymLink())
size = -;
return size;
} QString displayType;
QIcon icon; private :
QFileInfo mFileInfo;
}; class QFileIconProvider; class Q_AUTOTEST_EXPORT QFileInfoGatherer : public QThread
{
Q_OBJECT Q_SIGNALS:
void updates(const QString &directory, const QVector<QPair<QString, QFileInfo> > &updates);
void newListOfFiles(const QString &directory, const QStringList &listOfFiles) const;
void nameResolved(const QString &fileName, const QString &resolvedName) const;
void directoryLoaded(const QString &path); public:
explicit QFileInfoGatherer(QObject *parent = );
~QFileInfoGatherer(); // only callable from this->thread():
void clear();
void removePath(const QString &path);
QExtendedInformation getInfo(const QFileInfo &info) const;
QFileIconProvider *iconProvider() const;
bool resolveSymlinks() const; public Q_SLOTS:
void list(const QString &directoryPath);
void fetchExtendedInformation(const QString &path, const QStringList &files);
void updateFile(const QString &path);
void setResolveSymlinks(bool enable);
void setIconProvider(QFileIconProvider *provider); private Q_SLOTS:
void driveAdded();
void driveRemoved(); private:
void run() Q_DECL_OVERRIDE;
// called by run():
void getFileInfos(const QString &path, const QStringList &files);
void fetch(const QFileInfo &info, QElapsedTimer &base, bool &firstTime, QVector<QPair<QString, QFileInfo> > &updatedFiles, const QString &path); private:
mutable QMutex mutex;
// begin protected by mutex
QWaitCondition condition;
QStack<QString> path;
QStack<QStringList> files;
// end protected by mutex
QAtomicInt abort; #ifndef QT_NO_FILESYSTEMWATCHER
QFileSystemWatcher *watcher;
#endif
#ifdef Q_OS_WIN
bool m_resolveSymlinks; // not accessed by run()
#endif
QFileIconProvider *m_iconProvider; // not accessed by run()
QFileIconProvider defaultProvider;
}; QT_END_NAMESPACE
#endif // QFILEINFOGATHERER_H

函数QFileSystemModelPrivate::_q_fileSystemChanged的更多相关文章

  1. QFileSystemModel中通过flags函数反应代码的层级思考

    Qt的Model/View设计中,有一些隐藏的代码,它们大多放在私有类里,对于类的作用非常关键,体现着Qt的整体设计思想.然而,由于它们比较隐蔽,学习起来比较繁琐,受到人们的忽视.然而,体现设计思想, ...

  2. Python 小而美的函数

    python提供了一些有趣且实用的函数,如any all zip,这些函数能够大幅简化我们得代码,可以更优雅的处理可迭代的对象,同时使用的时候也得注意一些情况   any any(iterable) ...

  3. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  4. JavaScript权威指南 - 函数

    函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...

  5. C++对C的函数拓展

    一,内联函数 1.内联函数的概念 C++中的const常量可以用来代替宏常数的定义,例如:用const int a = 10来替换# define a 10.那么C++中是否有什么解决方案来替代宏代码 ...

  6. 菜鸟Python学习笔记第一天:关于一些函数库的使用

    2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...

  7. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

  8. 复杂的 Hash 函数组合有意义吗?

    很久以前看到一篇文章,讲某个大网站储存用户口令时,会经过十分复杂的处理.怎么个复杂记不得了,大概就是先 Hash,结果加上一些特殊字符再 Hash,结果再加上些字符.再倒序.再怎么怎么的.再 Hash ...

  9. JS核心系列:浅谈函数的作用域

    一.作用域(scope) 所谓作用域就是:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的. function scope(){ var foo = "global&quo ...

随机推荐

  1. c++_day5_成员指针

    1.成员指针实质:特定成员变量在对象实例中的相对地址. 2.类内可以直接初始化静态常量(声明部分).

  2. Redis(四)-持久化

    1.Redis将所有数据存储在内存中,从内存同步到磁盘上,就做持久化过程. 2.持久化有两种方式:rdb(Redis Database)和aof(Append of file) # rdb持久化方法: ...

  3. Windows系统Nessus离线(Offline) 版的安装

    Nessus离线(offline)版可以在局域网内进行系统漏洞扫描,下面简单介绍其windows系统版本的安装过程. 1.  登陆Tenable网站: https://www.tenable.com/ ...

  4. iphone上mitmproxy证书设置

    PC端安装mitmproxy并添加证书后,基本问题不大,都能正常运行起来 手机端iphone上下载安装mitmproxy证书: 1.手机和PC在同一个局域网中,设置wifi代理为PC端的ip,端口为m ...

  5. Promise的两种处理异步的方式

    单个异步处理: let usedMemoryPromise = fetchUsedMemeory(); usedMemoryPromise.then(data => {...}) functio ...

  6. document.body.scrollTop和document.documentElement.scrollTop 以及值为0的问题

    转自http://wo13145219.iteye.com/blog/2001598 一.先遇到document.body.scrollTop值为0的问题 做页面的时候可能会用到位置固定的层,读取do ...

  7. fiddler安装及mock数据

    1,fiddler安装,解决无法抓到https问题 可用本机的火狐浏览器测试,不行,就fiddler生成证书,拷到火狐里 在firefox中,选项->进入配置界面:高级-> 证书 -> ...

  8. _proto_理解

    一个对象就是一个属性集合,并拥有一个独立的prototype(原型)对象.这个prototype可以是一个对象或 者null. 一个对象的prototype是以内部的[[Prototype]]属性来引 ...

  9. springboot之jackson的两种配置方式

    springboot 针对jackson是自动化配置的,如果需要修改,有两种方式: 方式一:通过application.yml 配置属性说明:## spring.jackson.date-format ...

  10. UIPath Level 2&3

    Level 3 走了很多弯路,但是学到了很多东西,贴一个Level3的吧,其他的省略了 认认真真独立做完Level3的两个POC,相信你对UIPath的理解会更深入一步 晚安,祝各位中秋节快乐!