9.5 监视文件和目录的变化

9.5 监视文件和目录的变化

  我们前面讲了如何通过QTextStream、QDataStream、QDir以及QFileInfo来获取文件的信息,但在实际的开发当中,我们往往需要对某些文件或目录进行一些读写操作,但往往在读写操作之前需要先对文件或目录的状态进行一个监控。以确保文件的实时状态。那么实际上在Qt中也有这样的类来监控文件或目录的实时状态,这个类就是所谓的QFileSystemWatcher。这个类可以通过例如addPath()来添加对单个目录的监视,也可以通过addPaths()来对多个目录的监视。如果想移除不需要的目录,那么就可以使用removePath()或removePaths()来移除不需要监视的目录。接下来我们通过一个案例来说明QFileSystemWatcher的使用。

  案例:使用QFileSystemWatcher来监视指定的目录。

  (1)新建Qt的GUI项目,项目名称为FileWatcher,将类名命名为Watcher,并将该类继承自QWidget类。不需要创建ui文件。

  (2)在watcher.h中添加以下成员,完成对界面基本的元素的布置以及必要的数据成员的声明。

#ifndef WATCHER_H
#define WATCHER_H
#include <QWidget>
#include <QDataStream>
#include <QDebug>
#include <QTextStream>
#include <QDir>
#include <QFileDialog>
#include <QMessageBox>
#include <QPushButton>
#include <QFileSystemWatcher>
#include <QFileInfo>
#include <QListWidget>
#include <QGridLayout>
#include <QFileInfoList>
class Watcher : public QWidget
{
    Q_OBJECT
public:
    Watcher(QWidget *parent = nullptr);
    ~Watcher();
private slots:
    void slotAddPath();
    void slotRemovePath();
private slots:
    void slotdirectoryChanged(const QString& path);
private:
    QPushButton*m_addPathPushButton;
    QPushButton*m_removePathPushButton;
    QListWidget*m_pathListWidget;
    QList<QListWidgetItem*>m_listItem;
private:
    QFileSystemWatcher*m_watcher;
private:
    QGridLayout*m_mainLayout;
};
#endif // WATCHER_H

  (3)在watcher.cpp中进行实现

#include "watcher.h"
Watcher::Watcher(QWidget *parent):QWidget(parent)
{
    this->setWindowTitle(QString("目录监视器"));

    m_watcher = new QFileSystemWatcher;
    m_addPathPushButton = new QPushButton("添加目录");
    m_removePathPushButton = new QPushButton("移除目录");
    m_pathListWidget = new QListWidget;
    m_mainLayout = new QGridLayout(this);
    m_mainLayout->addWidget(m_pathListWidget,0,0);
    m_mainLayout->addWidget(m_addPathPushButton,0,1);
    m_mainLayout->addWidget(m_removePathPushButton,0,2);

    connect(this->m_addPathPushButton,&QPushButton::clicked,this,&Watcher::slotAddPath);
    connect(this->m_removePathPushButton,&QPushButton::clicked,this,&Watcher::slotRemovePath);
    connect(this->m_watcher,&QFileSystemWatcher::directoryChanged,this,&Watcher::slotdirectoryChanged);
}
Watcher::~Watcher()
{
    delete m_mainLayout;
    m_mainLayout = nullptr;

    delete m_pathListWidget;
    m_pathListWidget = nullptr;

    delete m_addPathPushButton;
    m_addPathPushButton = nullptr;

    delete m_removePathPushButton;
    m_removePathPushButton = nullptr;

    delete m_watcher;
    m_watcher = nullptr;

}

void Watcher::slotAddPath()
{
    QString path = QFileDialog::getExistingDirectory(this,QString("选择一个目录"),"./");
    if(path.isEmpty())
    {
        QMessageBox::warning(this,QString("提示"),QString("未选择任何目录!"));
    }
    else
    {
        for(int i = 0;i < m_pathListWidget->count();++i)
        {
            if(m_pathListWidget->item(0)->text() == path)
            {
                QMessageBox::information(this,QString("提示"),QString("该目录已存在!"));
                return;
            }
        }
        m_pathListWidget->addItem(path);
        m_watcher->addPath(path);
    }
}

void Watcher::slotRemovePath()
{
    //如果没有item,不能移除
    if(0 == m_pathListWidget->count())
    {
        QMessageBox::warning(this,QString("提示"),QString("没有任何的目录,无法移除!"));
    }
    else
    {
        //获取到选中的目录的item
        QList<QListWidgetItem*>list = m_pathListWidget->selectedItems();
        for(int i = 0;i < list.count();i++)
        {
           QListWidgetItem*item = m_pathListWidget->takeItem(m_pathListWidget->row(list.at(i)));
           m_watcher->removePath(item->text());
           list.removeAt(i);
           delete item;
           item = nullptr;
        }
    }

}

void Watcher::slotdirectoryChanged(const QString &path)
{
    QMessageBox::information(this,QString("提示"),QString("%1中的内容发生了变化!").arg(path));
}

  (4)运行,当我们添加桌面这个目录进行监视时,我们在桌面创建一个文件或文件夹时,就会出现提示窗口

  (5)对QFileSystemWatcher的一些总结

//对于QFileSystemWatcher这个类,它的成员都较为简单,这里就只简单做一个说明,这些成员看起来都非常的简单易懂。

//1.构造器
//QFileSystemWatcher::QFileSystemWatcher(const QStringList &paths, QObject *parent = nullptr)//构造一个对多个path目录进行监视的Watcher对象,这里面使用了StringList来存储这些需要被监视的目录
//QFileSystemWatcher::QFileSystemWatcher(QObject *parent = nullptr)//构造一个空的,但指定基类的空的Watcher对象

//2.bool QFileSystemWatcher::addPath(const QString &path)
//该函数用于往Watcher中添加一个目录进行监视,如果目录不存在或者是已经有这个目录在被监视了,就会返回false

//3.QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
//该函数用于一次性添加多个目录进行监视,会返回没有被监视的目录(也就是已经被添加过的,或者是目录不存在的)

//4.QStringList QFileSystemWatcher::directories() const
//返回此时此刻正在被监视的目录列表

//5.QStringList QFileSystemWatcher::files() const
//返回此时此刻正在被监视的文件列表

//6.bool QFileSystemWatcher::removePath(const QString &path)
//从被监视的目录中移除指定的目录,不对其进行监视,返回true则移除成功,否则移除失败

//7.QStringList QFileSystemWatcher::removePaths(const QStringList &paths)
//从被监视的目录中移除多个目录,并返回没有被成功移除的目录的列表


//信号
//void directoryChanged(const QString &path)//当目录中的内容发生改变时,会发出此信号,参数就是哪个目录中的内容发生了变化
//void fileChanged(const QString &path)//当文件的内容发生了变化时,会发出此信号,参数为哪个文件的内容发生了改变 

  本节代码:https://files.cnblogs.com/files/blogs/792763/FileWatcher.zip?t=1720263231&download=true

posted @ 2024-07-06 19:30  蜡笔小新Pointer  阅读(45)  评论(0)    收藏  举报