函数QFileSystemModelPrivate::_q_fileSystemChanged
由于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的更多相关文章
- QFileSystemModel中通过flags函数反应代码的层级思考
Qt的Model/View设计中,有一些隐藏的代码,它们大多放在私有类里,对于类的作用非常关键,体现着Qt的整体设计思想.然而,由于它们比较隐蔽,学习起来比较繁琐,受到人们的忽视.然而,体现设计思想, ...
- Python 小而美的函数
python提供了一些有趣且实用的函数,如any all zip,这些函数能够大幅简化我们得代码,可以更优雅的处理可迭代的对象,同时使用的时候也得注意一些情况 any any(iterable) ...
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- JavaScript权威指南 - 函数
函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...
- C++对C的函数拓展
一,内联函数 1.内联函数的概念 C++中的const常量可以用来代替宏常数的定义,例如:用const int a = 10来替换# define a 10.那么C++中是否有什么解决方案来替代宏代码 ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
- javascript中的this与函数讲解
前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...
- 复杂的 Hash 函数组合有意义吗?
很久以前看到一篇文章,讲某个大网站储存用户口令时,会经过十分复杂的处理.怎么个复杂记不得了,大概就是先 Hash,结果加上一些特殊字符再 Hash,结果再加上些字符.再倒序.再怎么怎么的.再 Hash ...
- JS核心系列:浅谈函数的作用域
一.作用域(scope) 所谓作用域就是:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的. function scope(){ var foo = "global&quo ...
随机推荐
- ABP EventBus(事件总线)
事件总线就是订阅/发布模式的一种实现 事件总线就是为了降低耦合 1.比如在winform中 到处都是事件 触发事件的对象 sender 事件的数据 e 事件的处理逻辑 方法体 通过E ...
- python 写文本文件出现乱码
最近工作中想完善一下监控日志,同事说客户突然说我们最近几天推送的数据只有几家,赶紧看预警,应推4700多家,实推3400多家,用户可能是看错了,但我记得当时项目验收上线时,这个来源的推送数据肯定是可以 ...
- maven install报错 Failed to execute goal on project my-manager-mapper: Could not resolve dependencies for project com.my:my-manager-mapper:jar:0.0.1-SNAPSHOT:
报错信息为: [ERROR] Failed to execute goal on project my-manager-mapper: Could not resolve dependencies f ...
- 初识Log4Net
刚刚了解log4net,根据自己的理解翻译了一下比较重要的东西.详细状况请见log4net官方网站 log4net是一种帮助程序员将日志语句输出到各种目标文件的输出工具,有了log4net,就可以在运 ...
- 可编程并行接口8255A详解
- python3.7导入gevent模块报错的解决方案
最近更新了python解释器3.7 结果安装gevent,在导入gevent之后就报错了,错误信息如下 RuntimeWarning: greenlet.greenlet size changed, ...
- C++ 中缀转后缀表达式并求值
//中缀转后缀 #include<iostream> #include<stack> using namespace std; int prio(char x){ ; ; ; ...
- Js 语言中 变量提升问题
变量提升: 提升变量的声明. 函数声明式: 像这种形式: function foo() {}: 会发生变量提升. 函数表达式: var fn=function fn(){}: 不会发生变量提升.var ...
- java通过HttpClient方式和HttpURLConnection方式调用WebService接口
1.引入maven依赖: <dependency> <groupId>org.apache.httpcomponents</groupId> <artifac ...
- lldb调试mysql 插件命令
# attach process llvm process attach --pid 64924 # 添加断点 breakpoint set -n dispatch_command(enum_ ...