QT使用QFileSystemModel实现的文件资源管理器(开源)

本文详细介绍了使用QFileSystemModel和QListView构建的文件管理器,包括文件复制、粘贴、重命名、显示详细信息以及路径导航栏的实现。同时提到了双击处理、事件过滤器的应用和一些待完善的功能。
摘要由CSDN通过智能技术生成

效果图

在这里插入图片描述

现实的功能

  1. 支持文件/文件夹复制,粘贴,剪切,删除,重命名的基本操作
  2. 支持打开图片,文档等资源
  3. 支持文件显示详细信息
  4. 支持文件路径导航
  5. 支持文件拖入文件夹

总体框架

  • 本案例主要使用了QFileSystemModelQListView。上方的路径导航栏使用了QListWidget,每一个路径名为一个item。关键在于你对QFileSystemModel 的使用。
  • 下述代码可能已经更新,最新代码请到文末源码里拉取

功能介绍

视图
  • 创建QFileSystemModel 模型与QListView视图,并设置相关参数,就可以显示本地的文件目录。关键在于要设置setViewMode函数。
// 创建文件系统模型
model = new QFileSystemModel(this);
model->setRootPath(QDir::homePath());

// 创建ListView并设置其模型
listView = new FileListView(this);
listView->setModel(model);
listView->setRootIndex(model->index(QDir::homePath()));
// 禁止拖拽
listView->setDragEnabled(false);
listView->setMovement(QListView::Static);
// 设置文件系统视图为大图标模式
listView->setViewMode(QListView::IconMode);
listView->setResizeMode(QListView::Adjust);
listView->setSpacing(20);
listView->setIconSize(QSize(48, 48));
listView->setGridSize(QSize(80, 80));
listView->installEventFilter(this);
双击进入处理
  • 在进入下一级的时候,要判断是文件还是文件夹,文件夹则进入,文件则调用系统默认的软件打开。
void FileExplorer::onDoubleClicked(const QModelIndex &index)
{
    if (model->isDir(index))
    {
        listView->setRootIndex(index);
        updatePath(index);
    }
    else
    {
        QString filePath = model->filePath(index);
        // 处理文件的打开逻辑
        QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));
    }
}
复制与剪切
  • 复制与剪切的逻辑相似,需要维护一个保存要操作文件的路径,和判断是否为剪切的标志位。剪切就是使用复制,粘贴成功后删除原有的文件。
void FileExplorer::copyFileOrFolder()
{
    cutOperation = false;
    QModelIndexList indexes = listView->selectionModel()->selectedIndexes();
    listOfFilesToCopy.clear();
    for (QModelIndex index : indexes)
    {
        QString filePath = model->filePath(index);
        listOfFilesToCopy.append(filePath);
    }
    listView->clearSelection();
}

粘贴
  • 我们从复制/剪切下得到了需操作文件的路径,就可以使用copy函数实现粘贴,需要注意的是,要复制目录内容,需要递归地复制所有文件和子目录,若路径不存在则创建不存在的文件,不然无法复制粘贴成功,若是剪切,粘贴完后要删除原文件,并清空链表。
//代码过长略
重命名,新建
  • 这都简单略过
显示文件详细信息
  • 这个需要利用到事件过滤器,当判断到事件为 QEvent::ToolTip时,使用QToolTip显示得到的文件信息。
bool FileExplorer::eventFilter(QObject *watched, QEvent *event)
{
    // 验证事件是针对 listView 的
    if (watched == listView && event->type() == QEvent::ToolTip)
    {
        QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
        if (helpEvent)
        {
            QModelIndex index = listView->indexAt(helpEvent->pos());
            if (index.isValid())
            {
                QString toolTipText;
                QLocale locale;
                // 获取项的完整路径
                QString filePath = model->filePath(index);
                QFileInfo fileInfo(filePath);
                QString longDate = locale.toString(fileInfo.lastModified(), QLocale::LongFormat);
                toolTipText = QString("Name: %1\nSize: %2KB\nType: %3\nLast Modified: %4")
                                  .arg(fileInfo.fileName())
                                  .arg(!fileInfo.isFile() ? calculateFolderSize(filePath) : fileInfo.size() / 1024)
                                  .arg(!fileInfo.isFile() ? "file" : fileInfo.suffix())
                                  .arg(longDate);

                // 显示工具提示
                QToolTip::showText(helpEvent->globalPos(), toolTipText);
            }
            else
            {
                QToolTip::hideText();
                event->ignore();
            }
            return true; // 事件已处理
        }
    }
    // 如果不是自己处理的事件,调用基类的事件过滤器
    return QWidget::eventFilter(watched, event);
}
文件路径导航栏
  • 主要思想就是使用QListWidget,每当路径变化时,就使用文件名重新生成item,点击其中一个文件名时,就会拼接成正确的路径名从而实现跳转。
void FileListWidget::refresh(const QString &dir)
{
    this->clear();
    auto initlist = dir.split("/");
    for (auto &str : initlist)
    {
        QListWidgetItem *item = new QListWidgetItem(str, this);
        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
        addItem(">");
        addItem(item);
    }
}

void FileExplorer::onitemClicked(QListWidgetItem *item)
{
    if (!item)
        return;
    auto row = fileList->row(item) + 1;
    QString strdir;
    for (int i = 0; i < row; ++i)
    {
        QListWidgetItem *itemc = fileList->item(i);
        if (itemc->text() != ">")
        {
            strdir.push_back(QString(itemc->text() + "/"));
        }
    }
    strdir.chop(1);
    if (!strdir.isEmpty())
    {
        fileList->refresh(strdir);
        model->setRootPath(strdir);
        listView->setRootIndex(model->index(strdir));
    }
}

总结

  • 文件操作的功能基本实现,但还是存在一些BUG需要处理,有些功能可加入,待完善。
  • 知识理应共享,源码在此(持续优化)。
  • 14
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A: 以下是一个简单的Qt程序,实现了基本的文件管理功能。它包括一个文件列表,以及按钮和菜单栏,可以添加、删除和重命名文件。 ``` #include <QtWidgets/QApplication> #include <QtWidgets/QMainWindow> #include <QtWidgets/QTreeView> #include <QtWidgets/QFileSystemModel> #include <QtWidgets/QMenuBar> #include <QtWidgets/QToolBar> #include <QtWidgets/QPushButton> #include <QtWidgets/QInputDialog> #include <QtWidgets/QMessageBox> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0) : QMainWindow(parent) { setWindowTitle("File Manager"); setMinimumSize(600, 400); // 创建菜单栏 QMenuBar *menuBar = new QMenuBar(this); setMenuBar(menuBar); // 创建文件菜单 QMenu *fileMenu = menuBar->addMenu("File"); // 添加创建文件的按钮 QAction *createAction = fileMenu->addAction("Create file"); connect(createAction, &QAction::triggered, this, &MainWindow::createFile); // 添加删除文件的按钮 QAction *deleteAction = fileMenu->addAction("Delete file"); connect(deleteAction, &QAction::triggered, this, &MainWindow::deleteFile); // 添加重命名文件的按钮 QAction *renameAction = fileMenu->addAction("Rename file"); connect(renameAction, &QAction::triggered, this, &MainWindow::renameFile); // 创建工具栏 QToolBar *toolBar = new QToolBar(this); addToolBar(toolBar); // 添加创建文件的按钮到工具栏 QPushButton *createButton = new QPushButton("Create", this); toolBar->addWidget(createButton); connect(createButton, &QPushButton::clicked, this, &MainWindow::createFile); // 添加删除文件的按钮到工具栏 QPushButton *deleteButton = new QPushButton("Delete", this); toolBar->addWidget(deleteButton); connect(deleteButton, &QPushButton::clicked, this, &MainWindow::deleteFile); // 添加重命名文件的按钮到工具栏 QPushButton *renameButton = new QPushButton("Rename", this); toolBar->addWidget(renameButton); connect(renameButton, &QPushButton::clicked, this, &MainWindow::renameFile); // 创建文件列表树视图和文件系统模型 QTreeView *fileTreeView = new QTreeView(this); setCentralWidget(fileTreeView); QFileSystemModel *fileModel = new QFileSystemModel(this); fileModel->setRootPath(QDir::rootPath()); fileTreeView->setModel(fileModel); } private slots: void createFile() { // 获取当前所在目录的路径 QModelIndex index = centralWidget()->currentIndex(); QString path = static_cast<QFileSystemModel*>(centralWidget()->model())->filePath(index); // 弹出文件名输入框,创建文件 QString fileName = QInputDialog::getText(this, "Create a file", "File name:"); QFile file(path + QDir::separator() + fileName); if (file.open(QIODevice::WriteOnly)) { file.close(); } } void deleteFile() { // 获取选中文件的路径 QModelIndex index = centralWidget()->currentIndex(); QString path = static_cast<QFileSystemModel*>(centralWidget()->model())->filePath(index); // 删除文件 if (!QFile::remove(path)) { QMessageBox::critical(this, "Error", "Failed to delete file"); } } void renameFile() { // 获取选中文件的路径 QModelIndex index = centralWidget()->currentIndex(); QString path = static_cast<QFileSystemModel*>(centralWidget()->model())->filePath(index); // 弹出文件名输入框,重命名文件 QString newName = QInputDialog::getText(this, "Rename file", "New name:", QLineEdit::Normal, path.section(QDir::separator(), -1)); QString newPath = path.section(QDir::separator(), 0, -2) + QDir::separator() + newName; if (!QFile::rename(path, newPath)) { QMessageBox::critical(this, "Error", "Failed to rename file"); } } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow window; window.show(); return app.exec(); } #include "main.moc" ``` 这段程序使用Qt Widgets模块来创建了一个主窗口,包含了一个菜单栏、工具栏和文件列表树视图。主窗口中还包括三个按钮,分别用于创建、删除和重命名文件。通过文件系统模型,可以将文件显示在其中。 在程序中,实现了三个槽函数,分别用于创建、删除和重命名文件。创建文件时,弹出一个文件名输入框,用户输入文件名后,创建文件。删除文件时,获取当前选中的文件路径,删除文件。重命名文件时,弹出一个文件名输入框,用户输入新的文件名后,重命名文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值