На этом шаге рассмотрим класс QFileSystemWatcher.
Такой механизм реализует класс QFileSystemWatcher. Его применение сводится к тому, что следует добавить методом addPath() нужный вам путь к файлу либо к каталогу, а когда необходимость в наблюдении за ним отпадет, удалить при помощи метода removePath(). При изменениях файла отправляется сигнал fileChanged(), а если изменен каталог — сигнал directoryChanged(). Оба сигнала передают в качестве параметра путь, по которому произошли изменения. Уведомления о изменениях осуществляются асинхронно и не блокируют выполнение основного потока. Для иллюстрации вышесказанного реализуем программу, которая будет принимать в командной строке каталоги и файлы и отображать их при изменениях (рис. 1).
Рис.1. Наблюдение за изменением файлов и каталогов
В заголовочном файле этого приложения описан класс Watcher:
//унаследуем QTextEdit class Watcher : public QTextEdit { Q_OBJECT public: Watcher(QWidget* pwgt = 0); //слоты для отображения пути измененного каталога slotDirectoryCh() //и пути и имени измененного файла slotFileCh() private slots: void slotDirectoryCh(const QString&); void slotFileCh (const QString&); };
Рассмотрим реализацию конструктора и слотов:
//присваиваем надпись для основного окна приложения Watcher::Watcher(QWidget* pwgt /*=0*/) : QTextEdit(pwgt) { setWindowTitle("Наблюдатель"); } //выполняем отображение информации при вызовах слотов void Watcher::slotDirectoryCh(const QString& str) { append("Каталог изменен:" + str); } void Watcher::slotFileCh(const QString& str) { append("Файл изменен:" + str); }
приведем текст файла main.cpp
int main(int argc, char** argv) { QApplication app(argc, argv); //создаем объекты наблюдателя (watch) и QFileSystemWatcher watch; //виджета для отображения информации (view) Watcher view; //из объекта приложения (app) запрашиваем список параметров, //переданных пользователем в командной строке (метод arguments()) QStringList args = app.arguments(); //убираем самый первый элемент списка, //т. к. он является именем нашей программы args.removeFirst(); //полученный список передаем объекту наблюдателю //и для этого вызываем метод QFileSystemWatcher::addPaths(). //Объект наблюдателя автоматически анализирует и распознает, //что из списка является каталогом, а что файлом watch.addPaths(args); //для того чтобы увидеть результат этого анализа, //отдельно отобразим файлы (метод QFileSystemWatcher::files()) //и каталоги (метод QFileSystemWatcher:: directories()) view.append("Наблюдаемый файл:" + watch.files().join(";")); view.append("Наблюдаемый каталог:" + watch.directories().join(";")); view.show(); //связываем сигналы объекта наблюдателя QFileSystemWatcher::directoryChanged() //и QFileSystemWatcher::fileChanged() со слотами slotDirectoryCh() //и slotFileCh() виджета отображения QObject::connect(&watch, SIGNAL(directoryChanged(const QString&)), &view, SLOT(slotDirectoryCh(const QString&))); QObject::connect(&watch, SIGNAL(fileChanged(const QString&)), &view, SLOT(slotFileCh(const QString&))); return app.exec(); }
Файлы приложения можно взять здесь.
На следующем шаге рассмотрим потоки ввода-вывода.