⭐️我叫恒心,一名喜欢书写博客的研究生在读生。
原创不易~转载麻烦注明出处,并告知作者,谢谢!!!
这是一篇近期会不断更新的博客欧~~~ 有什么问题的小伙伴 欢迎留言提问欧。
功能点一:文件查找与现实
0、知识点
- 打开文件管理器进行目录选择
- 记忆下拉框的内容
filetable
使用- 文件信息显示
- 文件图标的获取
- 自定义排序
1、 确定需求
- 在搜索栏输入关键字,快速搜索系统桌面目录里的文件和文件夹,展示在列表中,包含程序图标、名称、路径、大小信息。
注:
a. 文件夹无需展示大小
b. 搜索结果无需包含桌面文件夹中的子文件和子文件夹;
文件夹无需显示大小:
// 大小
QTableWidgetItem *sizeItem = nullptr;
// 如果是目录则sizeItem值为空
QFileInfo fileInfo(filePath);
if(fileInfo.isDir()){
// 如果是目录,直接设置为nullptr, 不显示大小
sizeItem = nullptr;
}else{
// 如果是目录,计算文件大小并设置为sizeItem
sizeItem = new QTableWidgetItem(tr("%1 KB")
.arg(int((size + 1023) / 1024)));
sizeItem->setData(absoluteFileNameRole, QVariant(filePath));
sizeItem->setToolTip(toolTip);
sizeItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
sizeItem->setFlags(sizeItem->flags() ^ Qt::ItemIsEditable);
}
2、 查找和文件目录选择
如果是只通过编写代码的话,就直接通过connect
函数进行槽的绑定就可以啦。
这里主要尝试ui下的槽函数,可视化添加槽。
具体的槽函数实现功能:
// 当查找的按钮被触碰时触发的槽函数
void MainWindow::on_findButton_clicked()
{
// 注意这里用的filesTable 是wiget类型的
ui->filesTable->setRowCount(0);
QString fileName = ui->fileComboBox->currentText();
QString text = ui->textComboBox->currentText();
QString path = QDir::cleanPath(ui->directoryCombox->currentText());
// 查找并显示文件
currentDir = QDir(path);
// 更新目录
watcher.removePath(currentDir.path());
watcher.addPath(path);
findFilesInDirectory(path, ui->fileComboBox->currentText(), ui->textComboBox->currentText());
QStringList files;
// 文件名进行查找文件
findRecursion(path, fileName.isEmpty() ? QStringLiteral("*") : fileName, &files);
// 在已经查找出的文件进一步查找哪些包含了text
if(!text.isEmpty())
files = findFiles(files, text);
files.sort();
showFiles(files);
}
目录选择
void MainWindow::on_broweButton_clicked()
{
QString directory = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(this,
tr("Find Files"),
QDir::currentPath()));
if(!directory.isEmpty()){
if(ui->directoryCombox->findText(directory) == -1)
ui->directoryCombox->addItem(directory);
ui->directoryCombox->setCurrentIndex(ui->directoryCombox->findText(directory));
}
}
3、自定义排序
// 表头排序指示器
ui->filesTable->setSortingEnabled(true); // 允许排序
ui->filesTable->horizontalHeader()->setSortIndicatorShown(true); // 显示排序指示器
具体实现:
void MainWindow::createFilesTable()
{
ui->filesTable = new QTableWidget(0,3);
ui->filesTable->setSelectionBehavior(QAbstractItemView::SelectRows);
QStringList labels;
labels << tr("Filename") <<tr("Path")<< tr("Size");
ui->filesTable->setHorizontalHeaderLabels(labels);
ui->filesTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
ui->filesTable->verticalHeader()->hide();
ui->filesTable->setShowGrid(false);
// 表头排序指示器
// ui->filesTable->setSortingEnabled(true); // 允许排序
// ui->filesTable->horizontalHeader()->setSortIndicatorShown(true); // 显示排序指示器
// 菜单
ui->filesTable->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->filesTable, &QTableWidget::customContextMenuRequested,
this, &MainWindow::contextMenu);
connect(ui->filesTable, &QTableWidget::cellActivated,
this, &MainWindow::openFileOfItem);
}
不过有点问题:
因为size
字段带了单位后是字符,字符的大小比较会有点问题,因此在实现中先关闭。
解决办法:
1、通过文本排序QTextListFormat
的style
和index
进行排序。
2、lamb表达式对排序规则进行自定义。
4、文件图标获取
QIcon icon = iconProvider.icon(filePath);
具体实现:
void MainWindow::showFiles(const QStringList &paths)
{
QFileIconProvider iconProvider;
for(const QString &filePath : paths){
// 获取图标
const QString toolTip = QDir::toNativeSeparators(filePath);
const QString relativePath = QDir::toNativeSeparators(currentDir.relativeFilePath((filePath)));
const qint64 size = QFileInfo(filePath).size();
QIcon icon = iconProvider.icon(filePath);
QTableWidgetItem *fileNameItem = new QTableWidgetItem(relativePath);
fileNameItem->setData(absoluteFileNameRole, QVariant(filePath));
fileNameItem->setToolTip(toolTip);
fileNameItem->setFlags(fileNameItem->flags() ^ Qt::ItemIsEditable);
// 添加图标进入名称的位置
fileNameItem->setIcon(icon);
// 添加路径
QTableWidgetItem *pathItem = new QTableWidgetItem(filePath);
pathItem->setData(absoluteFileNameRole, QVariant(filePath));
pathItem->setToolTip(toolTip);
pathItem->setFlags(fileNameItem->flags() ^ Qt::ItemIsEditable);
// 大小
QTableWidgetItem *sizeItem = nullptr;
// 如果是目录则sizeItem值为空
QFileInfo fileInfo(filePath);
if(fileInfo.isDir()){
// 如果是目录,直接设置为nullptr, 不显示大小
sizeItem = nullptr;
}else{
// 如果是目录,计算文件大小并设置为sizeItem
sizeItem = new QTableWidgetItem(tr("%1 KB")
.arg(int((size + 1023) / 1024)));
sizeItem->setData(absoluteFileNameRole, QVariant(filePath));
sizeItem->setToolTip(toolTip);
sizeItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
sizeItem->setFlags(sizeItem->flags() ^ Qt::ItemIsEditable);
}
int row = ui->filesTable->rowCount();
ui->filesTable->insertRow(row);
ui->filesTable->setItem(row, 0, fileNameItem);
ui->filesTable->setItem(row, 1, pathItem);
ui->filesTable->setItem(row, 2, sizeItem);
}
ui->fileFoundLabel->setText(tr("%n file(s) found (Double click on a file to open it)", nullptr, paths.size()));
ui->fileFoundLabel->setWordWrap(true);
}
5、目录查找范围
在findRecursion
函数中,这部分放在else循环外 遍历搜索的子目录。在内的话就不遍历子目录的内容
foreach (const QString& dir, currentDir.entryList(QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot))
{
findRecursion(prefix + dir, fileName, result);
}
6、 功能实现
最后 🐶狗头保命
一名喜欢书写博客的研究生在读生
如果觉得有用,麻烦三连支持一下欧,希望这篇文章可以帮到你,你的点赞是我持续更新的动力。
如果有感兴趣的小伙伴,欢迎留言后面会继续将笔记补上去~