在项目开发中,经常会遇到这样的问题:
当外部文件或文件夹被修改了,主程序如何马上知道文件已经被修改了呢?
一般情况,第一反应就是在程序中加入定时器,再约定时间间隔,定时检测文件状态,如果发现文件已经被修改,则发出信号,通知程序作相应处理。
但是,这样做很繁琐,不简洁,并且也比较耗性能,今天小豆君就来介绍下Qt是如何处理这种情况的。
下面,是我们的QFileSystemWatcher出场的时候了,哈,一看名字就很让人印象深刻,直接中式翻译“文件系统监视器”,顾名思义,就是监视文件系统变化的一个“小机器”。
那么,我们再来看一下这个类是继承谁的
喝,直接就是QObject,并且这家伙属性也没有。
那么,我们再看一下它的信号吧
目录改变信号,文件改变信号,参数分别是各自的路径。这货原来也可以监视目录变化,真是够周到的。
下面小豆君只讲文件的,对于文件夹大家类比即可。
那么,我该如何监视文件变化呢,你可以直接调用addPath()方法添加需要监视的文件,再调用connect函数连接fileChanged()信号和自定义槽,那么当文件发生变化时,就可以采取动作了,就是这么简单。
那有的小伙伴又要问了,那如果要监视多个文件呢,简单,Qt已经为你想好了,你可以直接调用addPaths()添加多个,或者重复调用addPath(),记住,一次性添加多个路径的函数只多了个s哦。
如果想要知道监视器都监视了哪些文件,调用files()即可。
好的,下面我们就写个小例子来看看怎么用吧。
参照下方ui图,本例可以在窗口左侧添加多个需要监视的文本文件,当文本文件被修改后,右侧显示修改后的文本内容
新建GUI应用程序项目FileWatcher,ui窗口类名FileWatcherWidget。
ui界面如下(左侧为QListWidget,右侧为QTextEdit):
filewatcherwidget.h
#ifndef FILEWATCHERWIDGET_H #define FILEWATCHERWIDGET_H #include <QWidget> #include <QFileSystemWatcher> namespace Ui { class FileWatcherWidget; } class FileWatcherWidget : public QWidget { Q_OBJECT public: explicit FileWatcherWidget(QWidget *parent = 0); ~FileWatcherWidget(); private slots: //点击添加按钮,添加要监视的文件 void on_btn_add_clicked(); //点击删除按钮,删除不需要监视的文件 void on_btn_del_clicked(); //当监视的文本文件发生变化时, //读取文本内容,并更新到右侧文本编辑器中 void onFileChanged(const QString& path); private: Ui::FileWatcherWidget *ui; QFileSystemWatcher* watcher;//监视器指针 }; #endif // FILEWATCHERWIDGET_H
filewatcherwidget.cpp
#include <QFileDialog> #include <QFile> #include "filewatcherwidget.h" #include "ui_filewatcherwidget.h" FileWatcherWidget::FileWatcherWidget(QWidget *parent) : QWidget(parent), ui(new Ui::FileWatcherWidget) { ui->setupUi(this); watcher = new QFileSystemWatcher(this); connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(onFileChanged(QString))); } FileWatcherWidget::~FileWatcherWidget() { delete ui; } void FileWatcherWidget::on_btn_add_clicked() { //打开txt文本文件 QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "./", tr("Text (*.txt)")); if (!fileName.isEmpty()) { if (watcher->addPath(fileName)) { //将文件路径添加到列表控件中 ui->listWidget->addItem(fileName); } } } void FileWatcherWidget::on_btn_del_clicked() { QListWidgetItem* item = ui->listWidget->currentItem(); if (item) { if (watcher->removePath(item->text())) { delete item; } } } void FileWatcherWidget::onFileChanged(const QString &path) { QFile file(path); if (file.open(QIODevice::ReadOnly|QIODevice::Text)) { QString text(file.readAll()); ui->textEdit->setText(text); file.close(); } }
然后编译运行程序,添加监视的文件,并修改保存文件,文本框中将会自动同步已经修改了的文件。
嘻嘻,不错吧,是不是Qt很给力,而且就几行代码就可以实现了。一般情况下,这种监视系统,经常会用到配置文件中,如果配置文件更改了,那程序就会去自动根据配置去更新程序或更新界面啦。
但是有一点要注意,如果被监视的文件被修改名字或删除,监视就会自动中断啦。
更多分享请关注微信公众号:小豆君Qt分享,只要关注,便可加入C++\Qt交流群,一起学习,更可获得所有文章源码。