Класс QFileSystemWatcher предназначет за отслеживанием изменений в файлах и директориях.
Например:
Устанавливаем слежку за каким то файлом, передавая классу полный путь к файлу. Как только файл будет переименован, изменен или удален с жесткого диска.
Простой пример применения:
В заголовчном файле определяем наследника класса: QFileSystemWatcher *fsWatcher;
Далле создаем тут же приватный слот, который будет срабатывать когда испустится сигнал объектом fsWatcher и на экран выведется сообщение о том, что файл изменен
Далее в файле исходников в конструкторе класса пишем следующее:
//Создаем наследника fsWatcher = new QFileSystemWatcher(this); //устанавливаем слежку на файл fsWatcher->addPath("/home/alexandr/test.txt"); //Связываем сигнал со слотом, как только файл будет изменен //произойдет вызов слота changed(QString) connect(fsWatcher, SIGNAL(fileChanged(QString)), this, SLOT(changed(QString)));
//Описываем наш слот void MainWindow::changed(const QString &flName) { //В QLabel будет выведено сообщение ui->label->setText("Changed " + flName); }
Допустим у нас приложение "Калькулятор". Имеется 9 кнопок с цифрами дабы не связывать каждое нажатие отдельной кнопочки с одним и тем же слотом обрабатывающим вывод цифры на табло и не плодить код, есть прекрасный класс в Qt - QSignalMapper
Простой пример:
В заголовочном файле декларируем:
QSignalMapper *signalMapper;
И тут же создаем приватный слот:
void clicked(const QString & text);
Который будет выводить сообщение с текстом нажатой кнопочки
Далее в конструкторе класса создаем объект класса QSignalMapper
signalMapper = new QSignalMapper(this);
Далее добавляем в QGridLayout yнаши 9 кнопочек:
for (int i = 0; i < 9; ++i) { //Кнопочка с текстом текущей итерации цикла QPushButton *button = new QPushButton(QString::number(i)); //При нажатии на данную кнопочку вызывам слот класса QSignalMapper connect(button, SIGNAL(clicked()), signalMapper, SLOT(map())); //Привязывем кнопочку к маперу с текстом текущей итерации signalMapper->setMapping(button, QString::number(i)); //ну и добавляем кнопочку в Layout ui->gridLayout->addWidget(button, i / 3, i % 3); } //Теперь когда маппер испуска сигнал о нажатии определенной кнопочки вызывается наш слот //и в него передается значение привязанное в мапер для данной кнопочки connect(signalMapper, SIGNAL(mapped(const QString &)), this, SLOT(clicked(const QString &)));
В C++ существует множество спецальных алгоритмов для работы с
массивами. Они позволяют сортировать данные в массиве, искать в нем
какое-либо значение, менять элементы местами и т.д. Для их работы вам
необходимо подкючить <algorithm> в начале программы.
Алгоритмы поиска.
Все алгоритмы поиска возвращают итератор на элемент, а не сам элемент.
find(begin,end,what) - ищет первый элемент со значенимем what в
промежутке begin - end, где begin и end - итераторы соответствующего
контейнера
adjacent_find(start,end) - ищет два последовательных совпадающих элемента между start и end и возвращает итератор на него
search(start,end,sbegin,send) - ищет между start и end последовательность sbegin-send
Иногда при разработке приложений возникает потребность в
существовании некоего объекта, который должен быть доступен из многих,
совершенно разных частей программы. Примером такого объекта может
служить общий контейнер внутренней конфигурации программы. Кроме того,
ключевой особенностью такого объекта является единственность его
существования – к примеру, объект, работающий с определенным COM портом
должен существовать в единственном экземпляре.
Таким образом, мы можем выделить две особенности объекта типа Singleton:
Доступность объекта из различных частей программы
Единственность существования
Специально выделяю вторую особенность, дабы подчеркнуть суть такого
объекта. Первая особенность – просто «полезность», вытекающая из
единственности. На практике, эти две особенности идут рядом, поэтому я
не буду разделять их детали реализации.
Да, вопрос об обоснованности существования таких объектов и т.п. –
это совсем другая тема и философия проектирования. Но мы сейчас не об
этом.
Существует несколько подходов к реализации таких объектов. Я
предлагаю один из них, которым пользуюсь уже на протяжении многих лет.
По умолчанию аргументы функции tr() воспринимаются в кодировке Latin-1. Для переопределения этого необходимо воспользоваться классом QTextCodec, а именно статической функцией QTextCodec::setCodecForTr().
Так как вызов функции QTextCodec::setCodecForTr() должен быть сделан до первого вызова tr(), то удобнее всего это реализовать сразу после создания объекта QApplication:
Длительные операции в программе можно разделить на две категории. Первая
— интенсивные вычислительные задачи, такие как: алгоритмы обработки
аудио и видео данных, моделирование. Вторая — взаимодействие с
медленными объектами «внешнего мира» программы(управление различным
промышленным оборудованием, загрузка файлов по сети и проч.). Для второй
категории задач проблема сохранения отзывчивости решается в Qt
использованием асинхронных классов, т.е. классов, методы которых сразу
после вызова возвращают управление, а о результате своей деятельности
они оповещают соответствующим сигналом. Примером таких классов могут
служить классы QFtp и QHttp.
В случае интенсивных вычислений (в не зависимости от использования
механизма сигнал-слот) обработка событий прерывается, сетевое
взаимодействие останавливается, таймеры замирают, программа не
перерисовывается и перестает отвечать на ввод пользователя. Иными
словами до окончания вычислений программа выглядит зависшей. Сохранить
отзывчивость программы можно либо периодической обработкой ожидающих в
очереди событий и тогда необходимые вычисления можно оставить в главном
потоке, либо созданием дополнительного потока и переносом вычислительных
алгоритмов в него. Создание многопоточных приложений требует высокой
квалификации от программиста и несколько усложняет код. Для тех, кого не
пугает усложнение исходного кода считаю необходимым напомнить первый
закон творческого программирования: «Caveat emptor: стоимость
сопровождения программного обеспечения пропорциональна квадрату
творческих способностей программиста». Выбор пути решения зависит от
задачи. Практически любую вычислительную задачу можно разбить на
несколько подзадач, на несколько частей. Если эти части могут быть
решены только последовательно, то велика вероятность того, что
оптимальным вариантом будут вычисления в главном потоке. Ежели отдельные
части независимы и могут вычисляться параллельно, то использование
нескольких потоков может дать значительный прирост производительности.
Самое простое решение заключается в периодическом вызове QCoreApplication::processEvents()
в коде вычислений. Эта функция обрабатывает ожидающие в очереди
события. В случае, если действия пользователя нежелательны во время
выполнения задачи можно отключить обработку событий мыши и клавиатуры
заменив вызов QCoreApplication::processEvents() на QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents). С помощью QCoreApplication::processEvents()
также можно «синхронизировать» асинхронные методы. Допустим у нас есть
класс для общения с неким устройством. Ему можно послать команду с
помощью метода send(QByteArray array) и получить ответ в слот data(QByteArray array)
в течение некоторого времени. На случай отсутствия ответа предусмотрим
таймаут. Если ответ не придет в течение 5 секунд, то ожидание мы
прекращаем.
Чтобы добавить информацию о версии в библиотеку достаточно включить следующую строку в файл проекта:
VERSION=1.2.3
В случае исполнимого файла все будет несколько сложнее. Для начала
создайте файл ресурсов myapp.rc и включите информацию о нем в файл
проекта:
RC_FILE = myapp.rc
Теперь отредактируем файл ресурсов:
#ifndef Q_CC_BOR # if defined(UNDER_CE) && UNDER_CE >= 400 # include <winbase.h> # else # include <winver.h> # endif #endif VS_VERSION_INFO VERSIONINFO FILEVERSION 0,2,0,0 PRODUCTVERSION 0,2,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x4L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "Application\0" VALUE "CompanyName", "SPECTRON NPO\0" VALUE "FileDescription", "XReport project\0" VALUE "FileVersion", "0, 2, 0, 0\0" VALUE "InternalName", "XReport\0" VALUE "LegalCopyright", "Copyright (C) 2008\0" VALUE "OriginalFilename", "XReport.exe\0" VALUE "ProductName", "XReport.exe\0" VALUE "ProductVersion", "0, 2, 0, 0\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END
Поместите файл иконки(пусть он будет зваться myappico.ico) в каталог с
исходными текстами программы. В том же каталоге создайте файл myapp.rc и
поместите в него следущую строчку:
IDI_ICON1 ICON DISCARDABLE "myappico.ico"
Добавьте информацию о файле ресурсов в ваш .pro файл:
RC_FILE = myapp.rc
И наконец, используя qmake, обновите ваши makefile файлы.