最近在学习QT
看的一本书叫《精通QT4编程》
第三章的一个例子:实现遍历文件夹,查找文件的功能。
我用的单一继承的方式,所以和书上有出入。
QT4.8.6版本可行~可写了不少时间呢
findfile.h:
#ifndef FINDFILE_H
#define FINDFILE_H
#include <QDialog>
#include <QDir>
#include <QStringList>
#include <QString>
#include <QTableWidgetItem>
#include <QFile>
#include <QFileInfo>
namespace Ui {
class findfile;
}
class findfile : public QDialog
{
Q_OBJECT
public:
explicit findfile(QWidget *parent = 0);
~findfile();
private slots:
void on_browseButton_clicked();
void on_findButton_clicked();
void on_stopButton_clicked();
void on_textLineEdit_textChanged(const QString &arg1);
private:
Ui::findfile *ui;
QStringList findFiles(const QDir&,const QString&,const QString&) ;
void showFiles(const QDir&dir, const QStringList&) ;
void tranvFolder(const QDir&,const QString&,const QString&);//实现对文件夹的递归查找
int m_ncount;//记录查找到文件的总数
bool m_bSensitive; //区分大小写为true
bool m_bSubfolder;//是否需要查找子文件 需要查找true
bool m_bStoped;//记录用户是否单击了“停止”按钮,true是,false没有
};
#endif // FINDFILE_H
findfile.cpp:
#include "ui_findfile.h"
#include <QtGui/QtGui>
#include <QtGui>
#include "findfile.h"
findfile::findfile(QWidget *parent) :
QDialog(parent),
ui(new Ui::findfile)
{
ui->setupUi(this);
ui->statusLabel->setText("就绪");
ui->resultLabel->setText("找到0个文件");
ui->nameComboBox->setEditText("*");
ui->dirComboBox->setEditText(QDir::currentPath());
//QString QDir::currentPath()区别一下
//QString QDir::dirName() const
ui->dirComboBox->addItem(QDir::currentPath());
ui->sensitiveCheckBox->setEnabled(false);
ui->stopButton->setEnabled(false); //初始化不可用
//区分一下单一继承方式和多继承方式
//我们这边都是弄得单一继承的方式
// m_ncount=0;
}
findfile::~findfile()
{
delete ui;
}
void findfile::on_browseButton_clicked()
{
//打开一个文件对话框,返回用户选择的文件系统中存在的路径
//参数说明:QDir::currentPath()应用程序所在的路径、初始化为文件对话框的当前目录;
// QFileDialog::ShowDirsOnly文件对话框只显示目录
QString dir=QFileDialog::getExistingDirectory(this,
"选择查找路径",QDir::currentPath(),QFileDialog::ShowDirsOnly);
if(!dir.isEmpty())
{
ui->dirComboBox->addItem(dir);//返回路径添加到“查找位置”下拉框
//设置为下拉框当前显示的内容
ui->dirComboBox->setCurrentIndex(ui->dirComboBox->currentIndex()+1);
}
}
void findfile::on_findButton_clicked()
{
//单击“查找”按钮之后
//改变按钮状态
ui->frame->setEnabled(false);//使用frame容器的目的就在此,其子窗口部件也不可用
//当查找按钮不可用时,停止按钮变成可用
ui->findButton->setEnabled(false);
ui->stopButton->setEnabled(true);//允许用户中断查找
ui->statusLabel->setText("正在搜索......");
ui->resultTableWidget->setRowCount(0);//清理显示结果,行数为0
//取得参数
QString fileName=ui->nameComboBox->currentText();
QString txt=ui->textLineEdit->text();
QString path=ui->dirComboBox->currentText();
m_bSubfolder=ui->subfolderCheckBox->isChecked();
m_bSensitive=ui->sensitiveCheckBox->isChecked();
//
m_ncount=0; //查找数清零
m_bStoped=false;
QDir dir=QDir(path);
if(fileName.isEmpty())
fileName="*";
tranvFolder(dir,fileName,txt);//文件查找函数
//至此,查找完成,后续工作开始
//用户中断(单击了“停止”按钮)
if(m_bStoped)
ui->statusLabel->setText("已中止");
else
ui->statusLabel->setText("就绪");
//恢复状态
ui->findButton->setEnabled(true);
ui->stopButton->setEnabled(false);
ui->frame->setEnabled(true);
}
void findfile::tranvFolder(const QDir& dir,const QString& fileName,const QString& txt)
{
if(m_bSubfolder)
{
QStringList folders;
//QDir::NoDotAndDotDot不是当前目录和当前目录的上一级目录
folders=dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);//获取当前文件夹下所有子文件夹的列表
for(int i=0;i<folders.size();i++)
{
qApp->processEvents();//事件处理函数,可响应用户的其他操作
if(m_bStoped)
break;
//获得子目录的绝对路径
QString strDir=QString("%1%2").
arg(dir.absolutePath()).arg(folders[i]);
tranvFolder(strDir,fileName,txt); //递归,进一步查找
}
}
QStringList files = findFiles(dir,fileName,txt);
showFiles(dir,files);
//showFiles(dir,files);
m_ncount +=files.size();
ui->resultLabel->setText(tr("找到%1个文件").arg(m_ncount));
//->setText("找到 %1 个文件").arg(m_ncount); !!!要看清楚
}
QStringList findfile::findFiles(const QDir& dir,const QString& fileName,const QString& txt)
{
QStringList files;
QStringList foundFiles;
//QDir::NoDotAndDotDot不是当前目录和当前目录的上一级目录
files=dir.entryList(QStringList(fileName), QDir::Files | QDir::NoSymLinks);
if(txt.isEmpty()) //不需要筛选
return files;
Qt::CaseSensitivity sensitive=Qt::CaseInsensitive;
if(m_bSensitive)
sensitive=Qt::CaseSensitive;
//判断是否区分大小写,将状态保存下来
for (int i=0; i<files.size();++i)
{
qApp->processEvents();
if(m_bStoped)
break;
QFile file(dir.absoluteFilePath(files[i]));
//QDir::absoluteFilePath()函数返回当前目录下一个文件的绝对目录
if(file.open(QIODevice::ReadOnly))
//QIODevice::ReadOnly参数指定了只读方式打开
{
QString line;
QTextStream in(&file);
//QTextStream提供文本进行读写的操作.
while(!in.atEnd())
{
if(m_bStoped)
break;
line=in.readLine();
//QTextStream::readLine()对文件进行读入操作
if(line.contains(txt,sensitive))
//QString::contains()对文本包含进行判断,直到QTextSteam::atEnds()判断已经到了文件尾
{
foundFiles<<files[i]; //foundFiles怎么感觉没有定义?写入时默认?
break;
}
}
}
}
return foundFiles;
}
//显示查找到的文件名
void findfile::showFiles(const QDir& dir,const QStringList& files)
{
for(int i = 0; i < files.size(); ++i)
{
QString strFilePath = dir.absoluteFilePath(files[i]); //取绝对路径
QFile file(strFilePath);
QFileInfo fileInfo(file); //文件信息对象
qint64 size = fileInfo.size(); //文件大小
QDateTime dateTime = fileInfo.created(); //文件创建时间
QString strDataTime = dateTime.toString(tr("yyyy MM月dd日hh::mm"));
QString strPermission; //文件权限
if(fileInfo.isWritable()) //文件可读
strPermission = ("w");
if(fileInfo.isReadable())
strPermission.append(" r");
if(fileInfo.isExecutable())
strPermission.append(" x");
QTableWidgetItem *fileNameItem =
new QTableWidgetItem(strFilePath);
fileNameItem->setFlags(Qt::ItemIsEnabled);
QTableWidgetItem* sizeItem = new QTableWidgetItem(tr("%1 KB")
.arg(int((size+1023)/1024)));
sizeItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
sizeItem->setFlags(Qt::ItemIsEnabled);
QTableWidgetItem* createdItem = new QTableWidgetItem(strDataTime);
QTableWidgetItem* permissionItem = new QTableWidgetItem(strPermission);
int row = ui->resultTableWidget->rowCount();
ui->resultTableWidget->insertRow(row);
ui->resultTableWidget->setItem(row,0,fileNameItem);
ui->resultTableWidget->setItem(row,1,sizeItem);
ui->resultTableWidget->setItem(row,2,createdItem);
ui->resultTableWidget->setItem(row,3,permissionItem);
}
}
void findfile::on_stopButton_clicked()
{
m_bStoped = true;
}
void findfile::on_textLineEdit_textChanged(const QString& txt)
{
if(txt.isEmpty()) //若文本为空,大小写复选框不可用
ui->sensitiveCheckBox->setEnabled(false);
else
ui->sensitiveCheckBox->setEnabled(true);
}