При написании одного проекта мне необходимо обрабатывать файлы, формируемые на основании полученных данных от инспектора машинного зрения. Содержимое файла — список штрих-кодов определенного количества, наименование файла — <год месяц день>_<штрих-код короба>. Эти файлы сохраняются в определенном каталоге, а формируются с периодичность N миллисекунд. Для тестирования приложения мне необходимо написать эмулятор такого «инспектора». Приложение будет формировать файлы со списком штрих-кодов и сохранять в заданный каталог.

Основной класс, отвечающий за работу эмулятора выглядит таким образом:
class emulator : public QObject
{
Q_OBJECT
public:
emulator(int codesCount, int codeLength, int startCodeIndex,
int startFileCodeIndex, int fileCodeLength, int millisec,
int filesCount, QString catalog);
~emulator();
public slots:
void startEmulating();
signals:
void startCodeIndexChanged(int);
void startFileCodeIndexChanged(int);
void logMessage(QString);
void finished();
private slots:
QString addZeros(QString str, int strLength);
QString fileName();
QStringList codesList();
void createTimer();
void saveFile();
void continueEmulating();
private:
int codesCount;
int codeLength;
int currentCodeIndex;
int currentFileCodeIndex;
int fileCodeLength;
int millisec;
int currentfilesCount;
int stopFilesCount;
QTimer *timer;
QString catalog;
};
Генерация файлов происходит по срабатыванию таймера и заканчивается, когда сформировано указанное в начальных значениях количество файлов.
Создание и запуск таймера:
timer = new QTimer(this);
timer->setInterval(millisec);
timer->setTimerType(Qt::PreciseTimer);
connect(timer, SIGNAL(timeout()), this, SLOT(continueEmulating()));
timer->start();
Объект timer удаляется при удалении объекта класса emulator. Тип таймера Qt::PreciseTimer отвечает за точность срабатывания до миллисекунды, как нам и необходимо. Слот continueEmulating() вызывает слот saveFile():
void emulator::saveFile()
{
QString fName = catalog+"/"+fileName();
QFile file(fName);
QTextStream out(&file);
if (!file.open(QIODevice::WriteOnly)) {
emit logMessage(tr("Ошибка открытия файла %1").arg(fName));
timer->stop();
emit finished();
}
//функция codesList() возвращает список штрих-кодов,
//записываем как объединенную строку через перенос \n
out << codesList().join("\n");
//сообщение основной программе
emit logMessage(fileName());
currentCodeIndex+=codesCount;
//сообщение об изменении значения счетчика
emit startCodeIndexChanged(currentCodeIndex);
currentFileCodeIndex++;
//сообщение об изменении значения счетчика
emit startFileCodeIndexChanged(currentFileCodeIndex);
file.close();
if (++currentfilesCount == stopFilesCount) {
timer->stop();
emit logMessage(tr("Генерация окончена: сформировано %1 файлов")
.arg(currentfilesCount));
emit finished();
}
}
Сигнал finished() посылается управляющему потоку для завершения операции и удаления объектов.
Создание объектов и запуск работы
После задания пользователем начальных значений, он нажимает на кнопку ОК и программа начинает работу. Для этого необходимо создать все объекты (эмулятора и потока):
emulator *emul = new emulator(ui->codesCount->value(),
ui->codeLength->value(),
ui->startCodeIndex->value(),
ui->startFileCodeIndex->value(),
ui->fileCodeLength->value(),
ui->timeout->value(),
ui->filesCount->value(),
ui->dir->text());
QThread *thrd = new QThread;
emul->moveToThread(thrd);
//после окончания формирования файлов сигнал для завершения работы потока
connect(emul, SIGNAL(finished()), thrd, SLOT(quit()));
//сигнал на удаление объекта эмулятора
connect(thrd, SIGNAL(finished()), emul, SLOT(deleteLater()));
//начало эмулирования
connect(thrd, SIGNAL(started()), emul, SLOT(startEmulating()));
//передача сообщения для записи в лог
connect(emul, SIGNAL(logMessage(QString)), this, SLOT(logMessage(QString)));
//изменение текущего значения индекса кода
connect(emul, SIGNAL(startCodeIndexChanged(int)),
this, SLOT(startCodeIndexChanged(int)));
//изменение текущего значения индекса кода в имени файла
connect(emul, SIGNAL(startFileCodeIndexChanged(int)),
this, SLOT(startFileCodeIndexChanged(int)));
//запуск
thrd->start();
Слот startEmulating() создает и запускает таймер.
Проект находится в открытом доступе на BitBucket.
Возможно, вам будет интересно взглянуть на мой другой проект в открытом доступе: DBRecordWidget — Библиотека-виджет для работы с данными.
Чтобы заказать проект или получить консультацию, перейдите, пожалуйста, на страницу Контакты.
Портфолио
Понравилось это:
Нравится Загрузка...
Похожие записи