1.先用Qt设计器设计出显示界面:
界面截图如下:
制作几面的关键在于,要把上半部分可以输入查找条件的输入框封装在一个frame容器中,用于最后关联信号量和槽函数时控制。
2.编写头文件,确定所需要的成员函数和成员变量
#include <QStringList>
#include <QDir>
#include <QtGui/QMainWindow>
#include "ui_qt_findfile.h"
class Qt_findfile : public QMainWindow
{
Q_OBJECT
public:
Qt_findfile(QWidget *parent = 0);
~Qt_findfile();
private:
Ui::FindFileFrom ui;
QStringList findFiles(const QDir&, const QString&, const QString&); //查找文件函数
void showFiles(const QDir&,const QStringList&); //显示查到的文件
void transFolder(const QDir&, const QString&, const QString); //当选择包含子文件时,需要递归查找的递归函数
bool m_bStopped; //是否停止查找
bool m_bSubfolder; //是否包含子文件
bool m_bSensitive; // 区分大小写
int m_nCount; //文件个数
private slots:
void browse(); //浏览槽函数
void find(); //查找按钮槽函数
void stop(); // 停止按钮槽函数
void doTxtChange(const QString&); //区分大小写选择框槽函数
};
3.函数具体实现
#include <QtGui>
#include "qt_findfile.h"
Qt_findfile::Qt_findfile(QWidget *parent)
: QMainWindow(parent),m_bStopped(false),m_nCount(0)
{
ui.setupUi(this);
ui.statusLabel->setText(tr("就绪 "));
ui.resultLabel->setText(tr("找到0个文件"));
ui.nameComboBox->setEditText("*");
ui.dirComboBox->setEditText(QDir::currentPath());
ui.dirComboBox->addItem(QDir::currentPath());
ui.sensitiveCheckBox->setEnabled(false);
ui.stopPushBtn->setEnabled(false);
connect(ui.findPushBtn, SIGNAL(clicked()), this, SLOT(find()));
connect(ui.stopPushBtn, SIGNAL(clicked()), this, SLOT(stop()));
connect(ui.closePushBtn, SIGNAL(clicked()), this, SLOT(close()));
connect(ui.browsePushBtn,SIGNAL(clicked()), this, SLOT(browse()));
connect(ui.txtLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(doTxtChange(const QString&)));
}
Qt_findfile::~Qt_findfile()
{
}
void Qt_findfile::browse()
{
QString dir = QFileDialog::getExistingDirectory(this,
tr("选择查找路径"),
QDir::currentPath(),
QFileDialog:: ShowDirsOnly); //返回文件系统存在的路径,只显示目录
if(!dir.isEmpty())
{
ui.dirComboBox->addItem(dir);
ui.dirComboBox->setCurrentIndex(ui.dirComboBox->currentIndex()+1);
}
}
void Qt_findfile::find()
{
ui.frame->setEnabled(false); //当点击查找按钮式,frame(输入查找条件那块需设置为不可用)
ui.findPushBtn->setEnabled(false);
ui.stopPushBtn->setEnabled(true); //停止查找按钮可用,允许用户中断查找
ui.statusLabel->setText(tr("正在搜索..."));
ui.resultTableWidget->setRowCount(0); //清理结果表格,归0
QString fileName = ui.nameComboBox->currentText();
QString txt = ui.txtLineEdit->text();
QString path = ui.dirComboBox->currentText();
m_bSubfolder = ui.subfoldCheckBox->isChecked();
m_bSensitive = ui.sensitiveCheckBox->isChecked();
m_nCount = 0;
m_bStopped = false;
QDir dir = QDir(path);
if(fileName.isEmpty())
{
fileName = "*";
}
transFolder(dir, fileName, txt);
if(m_bStopped)
{
ui.statusLabel->setText(tr("已中止"));
}
else
{
ui.statusLabel->setText(tr("就绪 "));
}
ui.findPushBtn->setEnabled(true);
ui.stopPushBtn->setEnabled(false);
ui.frame->setEnabled(true);
}
void Qt_findfile::transFolder(const QDir& dir,
const QString& fileName,
const QString txt) //查找文件,递归查找进入子文件
{
if(m_bSubfolder)
{
QStringList folders;
folders = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); //获取当前文件夹下所有子文件夹的列表
for(int i = 0; i < folders.size(); ++i)
{
qApp->processEvents(); //调用事件处理函数
if(m_bStopped)
{
break;
}
QString strDir = QString("%1/%2").arg(dir.absolutePath())
.arg(folders[i]);
transFolder(strDir, fileName, txt);
}
}
QStringList files = findFiles(dir, fileName, txt);
showFiles(dir, files);
m_nCount += files.size();
ui.resultLabel->setText(tr("找到 %1个文件").arg(m_nCount));
}
QStringList Qt_findfile::findFiles(const QDir& dir,
const QString& fileName,
const QString& txt) //文件查找
{
QStringList files = dir.entryList(QStringList(fileName),
QDir::Files | QDir::NoSymLinks); //获取fileName指定文件名的文件列表
if(txt.isEmpty())
return files;
QStringList foundFiles; //定义一查结果的列表
Qt::CaseSensitivity sensitive = Qt::CaseInsensitive; //初始化大小写区分为不区分
if(m_bSensitive)
{
sensitive = Qt::CaseSensitive;
}
for(int i = 0; i < files.size(); ++i)
{
qApp->processEvents();
if(m_bStopped)
{
break;
}
QFile file(dir.absoluteFilePath(files[i])); //构造返回文件的绝对路径名,
if(file.open(QIODevice::ReadOnly))
{
QString line;
QTextStream in(&file);
while(!in.atEnd())
{
if(m_bStopped)
break;
line = in.readLine();
if(line.contains(txt,sensitive))
{
foundFiles << files[i];
break;
}
}
}
}
return foundFiles;
}
void Qt_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 strDateTime = fileInfo.created();
QString strPermission;
if(fileInfo.isWritable())
{
strPermission = ("w");
}
if(fileInfo.isReadable())
{
strPermission = ("r");
}
if(fileInfo.isExecutable())
{
strPermission = ("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(strDateTime.toString("yyyy-MM-dd hh-mm-ss")); //进行类型转换
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 Qt_findfile::stop()
{
m_bStopped = true;
}
void Qt_findfile::doTxtChange(const QString& txt)
{
if(txt.isEmpty())
{
ui.sensitiveCheckBox->setEnabled(false);
}
else
{
ui.sensitiveCheckBox->setEnabled(true);
}
}