经过一段时间的学习,终于完成了文件系统的一个可视化与文件管理,简单记录一下整个程序的想法。
  主要分为以下几个模块:

1.界面搭建

2.目录树可视化

  此处通过QDir读取文件夹,然后通过QStandardItem创建目录树条目,在QTreeView中呈现。源码如下:

void Widget::loadLogFiles(const QString path, QStandardItemModel *model){model->removeRows(0, model->rowCount());QDir d(path);d.setFilter(QDir::Files           | QDir::Hidden |QDir::NoSymLinks      | QDir::AllDirs|QDir::NoDotAndDotDot);const QFileInfoList list = d.entryInfoList();int i=0;while(i<list.count()){QStyle *style = QApplication::style();QString fileType;QFileInfo file = list[i];LogStandardItem *dir = new LogStandardItem(file.fileName());dir->setCheckable(true);dir->setToolTip(file.path()+"/"+file.fileName());if(file.isDir()){dir->setIcon(style->standardIcon(QStyle::SP_DirIcon));fileType = "日志文件夹";}else{dir->setIcon(style->standardIcon(QStyle::SP_FileIcon));fileType = file.suffix();}QString sizeItem = QString::number(file.size());int rowItem = model->indexFromItem(dir).row();QString timeItem = QDateTime(file.lastModified()).toString("yyyy-MM-dd hh:mm:ss");model->appendRow(dir);model->setItem(rowItem, 1, new LogStandardItem(sizeItem));model->setItem(rowItem, 3, new LogStandardItem(timeItem));model->setItem(rowItem, 2, new LogStandardItem(fileType));if(file.isDir()) loadLogFiles(file.path()+"/"+file.fileName(), dir);i++;}
}void Widget::loadLogFiles(const QString path, QStandardItem *model){QDir d(path);d.setFilter(QDir::Files | QDir::Hidden |QDir::NoSymLinks | QDir::AllDirs|QDir::NoDotAndDotDot);const QFileInfoList list = d.entryInfoList();int i=0;while(i<list.count()){QStyle *style = QApplication::style();QString fileType;QFileInfo file = list[i];LogStandardItem *dir = new LogStandardItem(file.fileName());dir->setCheckable(true);dir->setToolTip(file.path()+"/"+file.fileName());if(file.isDir()){dir->setIcon(style->standardIcon(QStyle::SP_DirIcon));fileType = "日志文件夹";}else{dir->setIcon(style->standardIcon(QStyle::SP_FileIcon));fileType = file.suffix();}QString sizeItem = QString::number(file.size());QString timeItem = QDateTime(file.lastModified()).toString("yyyy-MM-dd hh:mm:ss");model->appendRow(dir);int rowItem = dir->index().row();model->setChild(rowItem, 1, new LogStandardItem(sizeItem));model->setChild(rowItem, 3, new LogStandardItem(timeItem));model->setChild(rowItem, 2, new LogStandardItem(fileType));if(file.isDir()) loadLogFiles(dir->toolTip(), dir);i++;}
}

3.复选框三态的实现

  由于设置复选框是针对每一个条目QStandardItem的,其本身是没有半选状态的,所以我们要重新实现QStandardItem的三态,从而让其具有父子之间的联系。我们创建一个继承QStandardItem类的子类,重写其setData函数,代码如下:

void LogStandardItem::setData(const QVariant &value, int role){if(role == Qt::CheckStateRole){Qt::CheckState CheckState = (Qt::CheckState) value.toInt();switch(CheckState){case Qt::Unchecked:{for(int i=0; i<rowCount(); i++){child(i)->setData(Qt::Unchecked, Qt::CheckStateRole);}QStandardItem::setData(value, role);if(parent()) parent()->setData(Qt::PartiallyChecked, role);}return;case Qt::PartiallyChecked:{Qt::CheckState current_state = checkState();int CheckedNum = 0;int UnCheckedNum = 0;bool isPartially = false;Qt::CheckState ChildState;int m_rowCount = rowCount();for(int i=0; i<m_rowCount; i++){ChildState = child(i)->checkState();switch(ChildState){case Qt::PartiallyChecked:       isPartially = true;break;case Qt::Unchecked:               UnCheckedNum++;break;case Qt::Checked:                CheckedNum++; break;default:                      CheckedNum++;break;}}Qt::CheckState NowState;if(isPartially)                     NowState = Qt::PartiallyChecked;else if(UnCheckedNum == m_rowCount) NowState = Qt::Unchecked;else if(CheckedNum == m_rowCount)   NowState = Qt::Checked;else                                NowState = Qt::PartiallyChecked;if(current_state != NowState){QStandardItem::setData(NowState, role);if(parent()) parent()->setData(Qt::PartiallyChecked, role);}}return;case Qt::Checked:{for(int i=0, num = rowCount(); i<num; i++){child(i)->setData(Qt::Checked, Qt::CheckStateRole);}QStandardItem::setData(value, role);if(parent()) parent()->setData(Qt::PartiallyChecked, role);}return;default:break;}}QStandardItem::setData(value, role);
}

实现了复选框的三态,其实就可以实现删除选中的文件或者文件夹的功能了。

4.双击显示日志内容

  对于此功能,我们采用子线程去读取日志内容,然后将读取的内容显示于控件当中。首先我们创建关于此功能的信号与槽:

connect(m_pLogTree, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(loadLogContent(QModelIndex)));

然后将所点击的目录对应的路径传输于子线程,设置信号与槽,在子线程读取完成以后主线程将内容显示。槽函数如下:

void Widget::loadLogContent(const QModelIndex &index){QStandardItem *item = m_pLogTreeModel->itemFromIndex(index);QFileInfo f(item->toolTip());if(f.isFile()){connect(&m_tShowLogContentThread, SIGNAL(readOverSignal()),this, SLOT(displayContent()));m_pContentDisplayWid->setToolTip(item->toolTip());m_tShowLogContentThread.m_sPath = item->toolTip();m_tShowLogContentThread.start();m_tShowLogContentThread.wait();m_pStatusBar->setText("正在浏览日志:"+f.fileName());}
}

在子线程中读取:

void ReadLogThread::run(){mutex.lock();QFile file(m_sPath);QTextStream contentRead(&file);QString content;m_lLogContent.clear();while(!contentRead.atEnd()){content = contentRead.readLine();m_lLogContent.append(content);}emit readOverSignal();mutex.unlock();
}

通过信号readOverSignal激活主线程槽函数displayContent,通过其来将内容显示于QListWidget中:

void Widget::displayContent(){QStringList disContent = m_tShowLogContentThread.m_lLogContent;// 如果日志数大于0,展示第一页,如果日志数=0, 依然显示0if(disContent.length() == 0) FlushContentPage(0);else FlushContentPage(1);
}void Widget::FlushContentPage(int page){m_nContentPage = page;while(m_pContentDisplayWid->count()>0){QListWidgetItem *item = m_pContentDisplayWid->takeItem(0);delete item;}if(m_nContentPage>0){QStringList disContent = m_tShowLogContentThread.m_lLogContent;for(int i=(m_nContentPage-1)*19; i<m_nContentPage*19 &&i<m_tShowLogContentThread.m_lLogContent.length(); i++){QListWidgetItem *Item = new QListWidgetItem(m_pContentDisplayWid);Item->setSizeHint(QSize(0, 20));Item->setText(qPrintable(m_tShowLogContentThread.m_lLogContent[i]));m_pContentDisplayWid->addItem(Item);}}QString pageInformation = QString::number(m_nContentPage) + "/" +QString::number(qCeil(m_tShowLogContentThread.m_lLogContent.length()*1.0/19*1.0));m_pShowPg->setText(pageInformation);
}

5.为QListWidget增加翻页功能

先创建控件,通过QSignalMapper 将多个按钮统一到一块,点击不同的按钮,QSignalMapper则会得到不同的索引值,从而根据索引值,来判断索要进行的操作。

QSignalMapper *btMapper = new QSignalMapper;
connect(m_pDelPgsBtn, SIGNAL(clicked(bool)), btMapper, SLOT(map()));
connect(m_pDelPgBtn, SIGNAL(clicked(bool)), btMapper, SLOT(map()));
connect(m_pAddPgBtn, SIGNAL(clicked(bool)), btMapper, SLOT(map()));
connect(m_pAddPgsBtn, SIGNAL(clicked(bool)), btMapper, SLOT(map()));
btMapper->setMapping(m_pDelPgsBtn, 0);
btMapper->setMapping(m_pDelPgBtn, 1);
btMapper->setMapping(m_pAddPgBtn, 2);
btMapper->setMapping(m_pAddPgsBtn, 3);
connect(btMapper, SIGNAL(mapped(int)), this, SLOT(TurnPage(int)));

然后创建对应的槽函数,以实现翻页功能:

void Widget::TurnPage(const int index){int page = m_nContentPage;switch (index) {case 0:     //向前翻十页if(page >10)             FlushContentPage(page-10);else if(page > 0)      FlushContentPage(1);else                    FlushContentPage(0);break;case 1:     // 向前翻一页if(page >1)            FlushContentPage(page-1);else if(page == 0)       FlushContentPage(0);break;case 2:     // 向后翻一页if(page < qCeil(m_tShowLogContentThread.m_lLogContent.length() * 1.0/19 * 1.0) && page != 0)FlushContentPage(page+1);else if(page == 0)        FlushContentPage(0);break;case 3:     // 向后翻十页if(page <= qCeil(m_tShowLogContentThread.m_lLogContent.length() * 1.0 / 19 * 1.0) - 10 && page != 0) FlushContentPage(page+10);else if(page != 0){page = qCeil(m_tShowLogContentThread.m_lLogContent.length()*1.0/19*1.0);FlushContentPage(page);}else                    FlushContentPage(0);break;}
}

6.检测文件夹

  如果文件夹中有新的文件,则展示于程序中,如果程序中某些对应的文件夹删除,则将其一并删除:同样此功能采用子线程来实现,子线程我们设置为2秒钟扫描一次文件夹:

void Widget::checkFileAndTree(){QTimer *tim = new QTimer();tim->start(2000);connect(tim, SIGNAL(timeout()), this, SLOT(checkFileAndTreeOnce()));
}void Widget::checkFileAndTreeOnce(){m_tUpdateTreeThread.start();m_tUpdateTreeThread.wait();
}

检测函数放于子线程中,此处呈现部分代码,其他的无非QStandardItemModel换成QStandardItem及之前的添加函数:

void UpdateTreeThread::run(){mutex.lock();checkFileInTree(m_sPath, m_tModel);checkTreeInFile(m_tModel);mutex.unlock();
}void UpdateTreeThread::checkFileInTree(QString path, QStandardItemModel *model){QDir d(path);d.setFilter(QDir::Files             | QDir::Hidden |QDir::NoSymLinks        | QDir::AllDirs|QDir::NoDotAndDotDot);const QFileInfoList list = d.entryInfoList();if(!list.length()) model->removeRows(0, model->rowCount());else if(!model->rowCount()) addLists(path, model);else{int i=0;while(i<list.length()){QFileInfo file = list[i];QString filePath = file.path()+"/"+file.fileName();bool fileExist = false;int j=0;while(j<model->rowCount()){if(filePath == model->item(j)->toolTip()){if(!fileExist){fileExist = true;if(file.isDir()) checkFileInTree(filePath, model->item(j));j++;}else model->removeRow(model->item(j)->row());}else j++;}if(!fileExist){QStyle *style = QApplication::style();QString fileType;LogStandardItem *item = new LogStandardItem(file.fileName());item->setCheckable(true);item->setToolTip(file.path()+"/"+file.fileName());if(file.isDir()){item->setIcon(style->standardIcon(QStyle::SP_DirIcon));fileType = "日志文件夹";}else{item->setIcon(style->standardIcon(QStyle::SP_FileIcon));fileType = file.suffix();}QString sizeItem = QString::number(file.size());QString timeItem = QDateTime(file.lastModified()).toString("yyyy-MM-dd hh:mm:ss");model->appendRow(item);int rowItem = item->index().row();model->setItem(rowItem, 1, new LogStandardItem(sizeItem));model->setItem(rowItem, 3, new LogStandardItem(timeItem));model->setItem(rowItem, 2, new LogStandardItem(fileType));if(file.isDir()) addLists(item->toolTip(), item);}i++;}}
}void UpdateTreeThread::checkTreeInFile(QStandardItemModel *model){if(model->rowCount() == 0)return;int i=0;while(i<model->rowCount()){QString path = model->item(i)->toolTip();QFileInfo file(path);if(!file.exists()) model->removeRow(model->item(i)->row());else{if(file.isDir()) checkTreeInFile(model->item(i));i++;}}
}

最终就可以实现上述文件呈现及对应的操作的功能。
  这段程序也有不足的地方,记录一下,以供以后努力:
1.代码模块化能力较弱
2.对于线程的使用水平太低
3.对于程序运行的成本考虑太少,严重浪费计算资源

文件系统可视化与文件管理相关推荐

  1. linux根-文件系统-目录管理-文件管理-用户及权限详解-用户组-用户管理-权限管理...

    一 .Linux文件结构 文件结构是文件存放在磁盘等存贮设备上的组织方法.主要体现在对文件和目录的组织上. 目录提供了管理文件的一个方便而有效的途径. Linux使用标准的目录结构,在安装的时候,安装 ...

  2. 操作系统 - 文件管理实验(文件系统)

    用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程,从而对各种文件操作命令的实质内容和执行过程有比较深入的了解. 要求设计一个 n 个用户的文件系统,每次用户可保存 m 个文件,用户在一次 ...

  3. 基于android的资源文件管理器

    软 件 学 院 毕业实训报告 课题名称: android资源管理器 专 业: 软件设计(游戏开发方向) 班 级: 学 号: 学生姓名: 指导教师: 年 月 日 摘 要 相信大家对Android的发展历 ...

  4. 根文件系统(rootfs)理解

    说明 最近学习了使用qemu搭建ARM vexpress环境,对rootfs有了一些大致理解并且对rootfs的构建做了些测试验证,特记录下. 简介 文件系统有两种意思: 文件管理系统,例如:ext2 ...

  5. linux管理控制面板--可视化管理linux

    市面上主要的网站主机分为三大类,具体差异简单说明: [虚拟主机]:也是大家口中说的"主机空间",可定制化低,适合纯小白和新手,完全不懂技术.说明白点,就是一台云服务器分割空间和内存 ...

  6. 操作系统文件管理实验

    1. 实验目的 用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程,从而对各种文件操作命令的实质内容和执行过程有比较深入的了解. 2. 实验内容与要求 要求设计一个 n个用户的文件系统,每 ...

  7. Linux系统结构和文件管理

    Linux系统的哲学之一就是一切皆文件.文件系统FHS和文件管理在Linux系统中占用很重要的地位. 1.linux系统结构 linux是一个倒树结构,linux中所有的东西都是文件. 这些文件都在系 ...

  8. 操作系统原理模拟实验(基于C/C++模拟处理机调度、存储管理和文件系统)

    目录 引言 一.处理机调度模拟 1.下载链接 2.目的与要求 3.截图示例 二.存储管理模拟 动态分区分配 1.下载链接 2.目的与要求 3.截图示例 分页存储地址转换 1.下载链接 2.目的与要求 ...

  9. kde 桌面显示管理器_KDE文件管理器Dolphin的综合指南

    kde 桌面显示管理器 自Fedora 10以来, Dolphin一直是KDE桌面的默认文件管理器.使用KDE作为桌面选项的其他发行版也将其用作默认文件管理器. 它非常强大,并提供了一些非常高级的功能 ...

最新文章

  1. 卫星发现一个重要信号:路上货车跑起来
  2. Java 虚拟机总结给面试的你(下)
  3. stm32非操作系统开发和带uCos的开发的区别,及一些解析
  4. 记录 grafana登录 从 go 迁移到 php
  5. java servlet 3_java – Servlet 2.5和3之间有什么区别?
  6. python rarfile不支持unicode_python – zipfile提取时的unicode错误
  7. hiho一下 第六十四周 Right-click Context Menu
  8. .so动态链接库文件
  9. 印染面料产品出现纬斜疵病,应该怎么防止?
  10. unity如何重新生成解决方案_揭秘Sherman:使用Unity制作影视级光照效果
  11. 第十一届蓝桥杯物联网设计与开发实验(合集)STM32学习
  12. android iCloud 短信,云助手 基于安卓的iCloud
  13. 计算机服务器组装,一台家用虚拟化测试服务器组装
  14. 第三章 代码的坏味道
  15. C++编程-牛客网-雀魂启动
  16. 统计学习方法chapter1
  17. win10计算机 需要新应用,手把手为你win10系统商店出现“需要新应用打开此ms-windows-store”的还原步骤...
  18. 苹果电脑虚拟键盘怎么打开
  19. iOS音乐播放器小技巧
  20. Java调用ffmepg+mencoder视频格式转换

热门文章

  1. BeanPostProcessor妙用(转载)
  2. 计算机操做系统(十二):进程同步和互斥
  3. oracle修改数据库用户名密码,怎样修改oracle数据库的用户名密码
  4. 连接到另外计算机要用户名,连接局域网电脑需要用户名密码
  5. 关于华为,一次不做评价的陈述
  6. 135编辑器html点击图片播放音乐,135微信编辑器怎样添加音乐 135编辑器添加音乐图文教程...
  7. 新技术加速隐私暴露,如何应对?
  8. 计算机专业买哪一款华硕电脑好,华硕电脑哪款好
  9. 天大计算机辅助设计与制造考题,2017年CAD工程师认证考题答案及解析
  10. mysql安装所需最低配置数据_MySQL的安装与基本配置