Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Диплом - Пояснительная Запсика, Сириченко Н.В..doc
Скачиваний:
0
Добавлен:
21.09.2019
Размер:
1.96 Mб
Скачать

5 Заключение

В данной дипломной работе была разработана и отлажена программа, отвечающая требованиям задания, обладающая должным функционалом и графическим интерфейсом. Возможности языка С++ позволили наделить программу должными функциями, а использование инструментария Qt увеличило скорость разработки. Быстродействие программы обеспечено многопоточной структурой, надежность установлена при помощи контрольных тестов с помощью специально разработанной программы-эмулятора пульта «КОРТ-М». Следует отметить, что, несмотря на то, что программа разрабатывалась в среде Microsoft Visual Studio и предназначена для выполнения на компьютерах с операционной системой семейства Windows NT, она может быть перенесена на иные операционные системы (UNIX-системы, Mac OS X, Android) путем простой компиляции исходного кода программы в соответствующих ОС.

Использование данной программы снимает с плеч инженеров-конструкторов работу по тестированию корректности работы приборов пульта, что ускоряет производственный процесс и исключает возможность ошибок, связанных с человеческим фактором. Весь комплекс тестов может быть выполнен с помощью пары щелчков мышью, отчеты тестирования сохраняются в файловом виде.

С экономической точки зрения трудоемкость разработки программы составила 169,21 часов, себестоимость – 112621 рубль 89 копеек.

Использование ЭВМ в управлении и тестировании контрольно- испытательной аппаратуры позволяет экономить материальные и человеческие ресурсы, так как рутинная, требующая долгой концентрации внимания работа, выполняется программой быстро и с соответствующими показателями надежности.

Список литературы

    1. Жасмин Бланшет, Марк Саммерфилд  Qt 4 Программирование GUI на С++. 2 издание, 2008

    2. Кардаш Г.Г.  Методические указания по курсовому и дипломному проектированию по предмету “Экономика отрасли”, 2003

    3. Электронная документация Qt – Qt Assistant

ПРИЛОЖЕНИЕ А

(обязательное)

Листинг программы

/************************************************************************

ДИПЛОМНАЯ РАБОТА

Разработал: Сириченко Н.В.

Версия: 2.00

Дата последних изменений: 22.04.2012

Название: Программа тестирования приборов пульта КОРТ-М

Задание: Необходимо создать программу для опрашивания приборов пульта сигналами команд, составления отчетов о тестировании на основании принятых ответов.

************************************************************************/

/************************************************************************

ОСНОВНАЯ ПРОГРАММА

************************************************************************/

#include <Windows.h>

#include <QTextCodec.h>

#include <QApplication.h>

#include "GeneratedFiles\moc_MainDialog.cpp"

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

MainDialog Window;

// Установка кодировки

QTextCodec *codec=QTextCodec::codecForName("Windows-1251");

QTextCodec::setCodecForLocale (codec);

QTextCodec::setCodecForCStrings (codec);

QTextCodec::setCodecForTr (codec);

// Кодировка - конец

if (argc==1)

Window.showWindow();

else

{

Window.hideMode();

return 0;

}

a.exec();

return 0;

}

/************************************************************************

ОБРАБОТЧИКИ СОБЫТИЙ ДИАЛОГОВОГО ОКНА

************************************************************************/

#include "GeneratedFiles\ui_MainDialog.h"

#include "XMLParser.h"

#include "GeneratedFiles\moc_COMProcessing.cpp"

class MainDialog:public QDialog

{

Q_OBJECT

private:

Ui_MainDialog Window;

int Tablerow;

XmlParser Parser;

SenderReciever COM;

progressBars Bars;

bool hiding;

public:

MainDialog ()

{

Window.setupUi(this);

Window.ListOfTables->hideColumn(1);

Tablerow=-1;

QObject::connect(Window.ListOfTables, SIGNAL (cellClicked (int,int)), this, SLOT (SetDataToTable(int,int)));

QObject::connect(Window.portNum, SIGNAL (currentIndexChanged(int)), this, SLOT (Activate(int)));

QObject::connect(&COM, SIGNAL (lockStartButton(bool)), this, SLOT (lockStartButton (bool)));

QObject::connect(&COM, SIGNAL (unlockStopButton(bool)), this, SLOT (unlockStopButton(bool)));

QObject::connect(&COM, SIGNAL (lockStepChooser(bool)), Window.cycleMode, SLOT (setDisabled (bool)));

QObject::connect(&COM, SIGNAL (finished()), this, SLOT (deactivated()));

QObject::connect(&COM, SIGNAL (currentTable(QString)), &Bars, SLOT(NewTable(QString)));

QObject::connect(&COM, SIGNAL (currentCommand(QString)), &Bars, SLOT(NewCommand(QString)));

QObject::connect(&COM, SIGNAL (gProgressValue(int)), &Bars, SLOT (setGeneralProgress(int)));

QObject::connect(&COM, SIGNAL (cProgressValue(int)), &Bars, SLOT (setCurrentProgress(int)));

QObject::connect(&COM, SIGNAL (timeToCloseBars()), this, SLOT (CloseTheBars()));

}

public slots:

void showWindow ()

{

Window.autoMode->setDisabled(true);

Window.manualMode->setDisabled(true);

Window.ListOfTables->setDisabled(true);

Window.DataTable->setDisabled(true);

Window.StartButton->setDisabled(true);

Window.ModeLabel->setDisabled(true);

Window.ChangeMode->setDisabled(true);

Window.ChangeTable->setDisabled(true);

Window.StopButton->setDisabled(true);

Window.cycleMode->setDisabled(true);

QFile settings(QCoreApplication::applicationDirPath()+'/'+"settings.txt");

int numb=0;

if (settings.open(QFile::ReadOnly))

{

QTextStream set(&settings);

set>>numb;

if (numb)

Window.portNum->setCurrentIndex(numb);

settings.close();

}

this->show();

}

void SetDataToTable (int row, int column)

{

if (COM.isRunning())

COM.terminate();

Window.ListOfTables->setDisabled(true);

if(Tablerow!=row)

{

Window.DataTable->setEnabled(true);

Tablerow=row;

QString path = Window.ListOfTables->item(row,1)->text();

ClearTable (Window.DataTable);

Parser.GetData(path, Window.DataTable);

Window.StartButton->setEnabled(true);

}

Window.ChangeTable->setDisabled(false);

Window.cycleMode->setDisabled(false);

}

void ClearTable (QTableWidget *table)

{

QTableWidgetItem *item;

while (item=table->item(0,0))

{

table->removeRow(0);

}

}

void Activate (int index)

{

if(index&&COM.OpenPort(index))

{

Window.portNum->setCurrentIndex(index);

Window.autoMode->setDisabled(false);

Window.manualMode->setDisabled(false);

Window.ModeLabel->setDisabled(false);

if (Window.manualMode->isChecked())

Window.ListOfTables->setEnabled(true);

QFile settings(QCoreApplication::applicationDirPath()+'/'+"settings.txt");

int numb=0;

if (settings.open(QFile::ReadWrite))

{

QTextStream set(&settings);

set>>numb;

if (index!=numb)

set<<index;

settings.close();

}

}

else

{

Window.autoMode->setDisabled(true);

Window.manualMode->setDisabled(true);

Window.ListOfTables->setDisabled(true);

Window.DataTable->setDisabled(true);

Window.StartButton->setDisabled(true);

Window.ModeLabel->setDisabled(true);

ClearTable (Window.DataTable);

Tablerow=-1;

QMessageBox errorBox;

errorBox.setIcon(QMessageBox::Information);

errorBox.setWindowTitle(QObject::tr("Ошибка открытия COM порта"));

errorBox.setText("Не удалось открыть порт, выберите другой");

errorBox.setStandardButtons(QMessageBox::Close);

errorBox.exec();

}

}

void on_manualMode_clicked ()

{

ClearTable (Window.ListOfTables);

Window.ListOfTables->setEnabled(true);

Window.ChangeMode->setEnabled(true);

Parser.GetTableList (Window.ListOfTables);

Window.autoMode->setDisabled(true);

Window.manualMode->setDisabled(true);

COM.setMode(true);

}

void on_autoMode_clicked ()

{

Window.autoMode->setDisabled(true);

Window.manualMode->setDisabled(true);

Window.ChangeMode->setEnabled(true);

ClearTable (Window.ListOfTables);

Parser.GetTableList (Window.ListOfTables);

Window.ListOfTables->setDisabled(true);

int position=0;

Window.DataTable->setDisabled(false);

for (int i=0; i<Window.ListOfTables->rowCount(); ++i)

{

QTableWidgetItem *currentItem = new QTableWidgetItem (Window.ListOfTables->item(i,0)->text());

currentItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

Window.DataTable->insertRow(position);

Window.DataTable->setSpan(position,0,1,4);

Window.DataTable->setItem(position,0,currentItem);

Window.DataTable->item(position,0)->setBackground(Qt::yellow);

position=Parser.GetData(Window.ListOfTables->item(i,1)->text(), Window.DataTable,position);

}

COM.setMode(false);

Window.StartButton->setDisabled(false);

Window.StartButton->setText("Начать проверку");

Bars.setGeneralProgress(0);

Bars.setCurrentProgress(0);

}

void on_ChangeMode_clicked ()

{

Window.autoMode->setDisabled(false);

Window.manualMode->setDisabled(false);

Window.autoMode->setChecked(false);

Window.manualMode->setChecked(false);

Window.ListOfTables->setDisabled(true);

ClearTable (Window.DataTable);

Window.DataTable->setDisabled(true);

Tablerow=-1;

Window.ChangeTable->setDisabled(true);

Window.cycleMode->setDisabled(true);

Window.StartButton->setDisabled(true);

}

void on_ChangeTable_clicked ()

{

ClearTable (Window.DataTable);

Window.ChangeTable->setDisabled(true);

Window.cycleMode->setDisabled(true);

Window.StartButton->setDisabled(true);

Window.ListOfTables->setDisabled(false);

Window.DataTable->setDisabled(true);

Tablerow=-1;

if (COM.isRunning())

COM.terminate();

}

void on_cycleMode_clicked ()

{

if(Window.cycleMode->checkState())

{

Window.StartButton->setText("Начать проверку");

COM.setCycleSending(true);

}

else

{

Window.StartButton->setText("Послать команду");

COM.setCycleSending(false);

}

}

void on_StartButton_clicked ()

{

hiding = false;

if (!COM.isRunning())

{

COM.setTable(Window.DataTable);

COM.start();

}

else

{

COM.SendNow(true);

}

if (Window.autoMode->isChecked())

{

COM.setTableCount(Window.ListOfTables->rowCount());

Bars.show();

this->setVisible(false);

Bars.exec();

}

}

void on_StopButton_clicked ()

{

if (COM.isRunning())

COM.terminate();

Window.StartButton->setDisabled(true);

Window.StopButton->setDisabled(true);

Window.ChangeTable->setDisabled(true);

ClearTable (Window.DataTable);

Window.ListOfTables->setDisabled(false);

}

public slots:

void lockStartButton (bool a)

{

Window.StartButton->setDisabled (a);

}

void unlockStopButton (bool a)

{

Window.StopButton->setEnabled(a);

}

void deactivated ()

{

Window.ChangeMode->setDisabled(false);

if (COM.isRunning()) COM.terminate();

}

void CloseTheBars ()

{

Bars.close();

if (hiding==false) this->setVisible (true);

}

void hideMode ()

{

if(COM.isRunning())

COM.terminate();

QFile settings(QCoreApplication::applicationDirPath()+'/'+"settings.txt");

int numb=0;

if (settings.open(QFile::ReadOnly))

{

QTextStream set(&settings);

set>>numb;

if (numb)

if (!COM.OpenPort(numb))

{

QMessageBox errorBox;

errorBox.setIcon(QMessageBox::Critical);

errorBox.setWindowTitle(QObject::tr("Ошибка открытия COM порта - программа проверки КОРТ-М"));

errorBox.setText("Запишите корректный номер COM порта в файл settings.txt в папке приложения!");

errorBox.setStandardButtons(QMessageBox::Close);

errorBox.exec();

return;

}else;

else

{

QMessageBox errorBox;

errorBox.setIcon(QMessageBox::Critical);

errorBox.setWindowTitle(QObject::tr("Ошибка открытия COM порта"));

errorBox.setText("Запишите номер COM порта в файл settings.txt в папке приложения!");

errorBox.setStandardButtons(QMessageBox::Close);

errorBox.exec();

return;

}

settings.close();

}

hiding = true;

ClearTable (Window.ListOfTables);

Parser.GetTableList (Window.ListOfTables);

int position=0;

for (int i=0; i<Window.ListOfTables->rowCount(); ++i)

{

QTableWidgetItem *currentItem = new QTableWidgetItem (Window.ListOfTables->item(i,0)->text());

currentItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

Window.DataTable->insertRow(position);

Window.DataTable->setSpan(position,0,1,4);

Window.DataTable->setItem(position,0,currentItem);

Window.DataTable->item(position,0)->setBackground(Qt::yellow);

position=Parser.GetData(Window.ListOfTables->item(i,1)->text(), Window.DataTable,position);

}

COM.setMode(false);

COM.setTableCount(Window.ListOfTables->rowCount());

COM.setTable(Window.DataTable);

COM.setHiding (true);

Bars.setGeneralProgress(0);

Bars.setCurrentProgress(0);

Bars.show();

COM.start();

Bars.exec();

this->close();

}

};

/************************************************************************

ПОТОК ПРОВЕРКИ

************************************************************************/

#pragma once

#include <QElapsedTimer.h>

#include <QTextStream.h>

#include <QTableWidget.h>

#include <QThread.h>

#include <QProcess.h>

#include <QMessageBox.h>

#include <windows.h>

#include <stdio.h>

#include "GeneratedFiles\ui_ProgressBars.h"

HANDLE Port;

int WhichPort, currentRow;

float CountOfTestTables;

COMSTAT St;

bool CycleSending=false, now=true;

bool mode, hiding; //true – ручной режим, false – автоматический режим

class progressBars:public QDialog

{

Q_OBJECT

private:

Ui_ProgressBars BarsWindow;

public:

progressBars ()

{

BarsWindow.setupUi(this);

BarsWindow.generalBar->setValue(0);

BarsWindow.currentBar->setValue(0);

}

void showWindow ()

{

this->show();

}

public slots:

void NewCommand (QString name)

{

BarsWindow.commandName->setText(name);

}

void NewTable (QString name)

{

BarsWindow.tableName->setText(name);

}

void setGeneralProgress (int a)

{

if (a<=100)

BarsWindow.generalBar->setValue (a);

else

BarsWindow.generalBar->setValue (100);

}

void setCurrentProgress (int a)

{

BarsWindow.currentBar->setValue (a);

}

};

class SenderReciever:public QThread

{

Q_OBJECT

private:

QTableWidget *table;

public:

QString getMaskFrom (const QString maskHandler)

{

QString mask;

return mask=maskHandler.left(18);

}

void setTable (QTableWidget *tableWidget)

{

table=tableWidget;

}

void setCycleSending (bool a)

{

CycleSending=a;

}

void setMode (bool a)

{

mode=a;

}

void SendNow (bool a)

{

now=a;

}

bool OpenPort (int num)

{

char path[16];

WhichPort=num;

sprintf(path,"\\\\.\\COM%d",WhichPort);

Port=CreateFileA

(path,

GENERIC_READ | GENERIC_WRITE, //Права доступа 0, //Используется в монопольном режиме

0, //Наследуем родительский дескриптор безопасности

OPEN_EXISTING, //Режим открытия

0, //Для асинхронной работы

0); //Без шаблона

if(Port==INVALID_HANDLE_VALUE)

return false;

//Настройка параметров порта

DCB d;

d.DCBlength=sizeof(DCB);

if(!GetCommState(Port,&d))

return false;

d.BaudRate = 17200; //Скорость работы

d.ByteSize= 8; //Размер "слова"

d.fAbortOnError = true; //Прерывание работы при ошибке

d.fParity = false; //Будет ли использываться четность

d.Parity = false; //Четность

d.StopBits = ONESTOPBIT; //Стоповые биты

if(!SetCommState(Port,&d))

return 1;

//Установка времени ожидания приёма/передачи //данных

COMMTIMEOUTS t = {0};

t.ReadIntervalTimeout=30;

t.ReadTotalTimeoutMultiplier=1;

t.ReadTotalTimeoutConstant=50;

//Настраиваем тайм-ауты порта

if(!SetCommTimeouts (Port, &t))

return false;

SetupComm(Port,1024*1024,1024);

//Очистить принимающий буфер порта

PurgeComm(Port, PURGE_RXCLEAR);

PurgeComm(Port, PURGE_TXCLEAR);

return true;

}

void SendCommand (int CommandRow)

{

QString command;

char commandbuf;

bool ok;

DWORD a;

QColor back;

back.setRgb(170,255,247);

command=table->item(CommandRow,1)->text();

command.remove(4,1);

commandbuf=command.toInt(&ok, 2);

if (!(ok&&WriteFile (Port,&commandbuf,1,&a,0)))

{

table->item(CommandRow,1)->setText("Команда не была отправлена!");

};

table->item(CommandRow,1)->setBackground(back);

table->item(CommandRow,0)->setBackground(back);

if (table->item(CommandRow,4))

msleep(table->item(CommandRow,4)->text().toInt());

}

void GetAnswer (int AnswerRow)

{

QElapsedTimer timer;

bool HasNotAnswer;

DWORD a;

unsigned char buf[255];

QChar zero='0';

timer.start();

do

{

HasNotAnswer=true;

ClearCommError(Port,0,&St);

if(St.cbInQue>=3) //Если буфер не пуст

{

QString toTable;

ReadFile (Port,buf,3,&a,0);

if (a)

{

for (int k=0; k<a; ++k) //Преобразование данных в читаемый вид

{

if (buf[k])

{

QString fromPort;

fromPort+=QString().setNum(buf[k],2);

if (fromPort.size()==8)

toTable+=fromPort;

else

{

int currentSize=fromPort.size();

for (int l=0; l<8-currentSize; ++l)

fromPort.insert(l,zero);

toTable+=fromPort;

}

}

else toTable+="00000000";

if(k!=a-1) toTable+=" ";

}

if(getMaskFrom(toTable)==getMaskFrom(table->item(AnswerRow,2)->text()))

{

table->item(AnswerRow,3)->setText(toTable);

HasNotAnswer=false;

}

}

}

if(timer.elapsed()>5000)

{

table->item(AnswerRow,3)->setText("Нет ответа 5 сек!");

table->item(AnswerRow,3)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

break;

}

else continue;

}

while (HasNotAnswer);

if (table->item(AnswerRow,2)->text()==table->item(AnswerRow,3)->text())

{

table->item(AnswerRow,2)->setBackground(Qt::green);

table->item(AnswerRow,3)->setBackground(Qt::green);

}

else

{

table->item(AnswerRow,2)->setBackground(Qt::red);

table->item(AnswerRow,3)->setBackground(Qt::red);

}

}

//Функция выравнивает поток считывания на нужный байт

void synchronization ()

{

unsigned char buf;

bool ok;

DWORD a;

QString IP = "00001100";

QString FF = "11111111", written;

buf=IP.toInt(&ok, 2);

WriteFile (Port, &buf, 1, &a, 0);

buf=FF.toInt(&ok, 2);

WriteFile (Port, &buf, 1, &a, 0);

do

{

ClearCommError(Port,0,&St);

if(St.cbInQue)

{

ReadFile (Port, &buf, 1, &a, 0);

written.setNum(buf,2);

if (written=="11111111")

break;

}

}

while (1);

}

void run ()

{

bool fl;

QColor error;

emit lockStepChooser (true);

emit unlockStopButton (true);

emit lockStartButton (true);

synchronization ();

if (mode)

{ //Ручной режим

if(CycleSending) //Таблица целиком

{

emit lockStartButton (true);

for (int i=0; i<table->rowCount(); ++i)

{

if (i==table->rowCount()-1&&table->item(i,2)==NULL)

break;

if(table->item(i,0)->text()!=" ")

{

SendCommand (i); //Если текущая позиция

//таблицы - команда, послать ее

}

else

if(table->item(i,2))

GetAnswer (i); //Tсли текущая позиция

//таблицы - ответ, считать его

}

}

else

{

currentRow=0;

int rowCount = table->rowCount();

emit lockStartButton (false);

do

{

if (currentRow==rowCount-1 &&

table->item(currentRow,1)==NULL &&

table->item(currentRow,2)==NULL)

break;

fl=false;

if(now)

{

emit lockStartButton (true);

if(table->item(currentRow,0)->text()!=" ")

{

SendCommand (currentRow);

}

else

if(table->item(currentRow,2))

GetAnswer (currentRow);

currentRow++;

fl=true;

now=false;

if(currentRow<table->rowCount() &&

table->item(currentRow,2) &&

table->item(currentRow,2)->text()!=" ")

now=true; //Автоитерация на прием ответа

}

if(fl) {emit lockStartButton (false); fl=false;}

}

while (!(currentRow==table->rowCount()));

}

}

else //Авторежим

{

float gprogressvalue=0, proc;

int forbars, donetables=0;

QColor check;

forbars=table->rowCount();

emit lockStartButton (true);

for (int i=0; i<table->rowCount(); ++i)

{

check=table->item(i,0)->background().color();

if(check==Qt::yellow)

{

if(donetables)

{

proc=donetables/CountOfTestTables;

proc*=100;

emit cProgressValue (proc);

}

donetables++;

emit currentTable (table->item(i,0)->text());

continue;

}

if(table->item(i,0)->text()!=" ")

{

emit currentCommand (table->item(i,0)->text());

SendCommand (i);

}

else

{ if(table->item(i,2))

GetAnswer (i);

gprogressvalue=i;

gprogressvalue/=forbars;

gprogressvalue*=100;

emit gProgressValue(gprogressvalue);

}

}

emit cProgressValue(100);

emit gProgressValue(100);

QString logpath = QCoreApplication::applicationDirPath()+'/'+"automodelog.log";

QFile log(logpath);

bool openLog = false;

//Запись лог-файла

if (log.open(QFile::WriteOnly))

{

QTextStream outlog(&log);

QString whitespace (" ");

QString incorrect (" (неверный ответ)");

QString title ("Лог-файл автоматического режима проверки приборов пульта КОРТ-М");

outlog<<title;

for (int i=0; i<table->rowCount(); ++i)

{

if(table->item(i,0)->background().color()==Qt::yellow)

{

outlog<<"\r\n";

outlog.flush();

outlog<<table->item(i,0)->text();

outlog<<"\r\n";

outlog.flush();

outlog<<"\r\n";

outlog.flush();

}

else

if (table->item(i,0)->text()!=" ")

{

outlog<<table->item(i,1)->text();

outlog<<"\r\n";

outlog.flush();

} else

if (table->item(i,3))

{

outlog<<whitespace<<table->item(i,3)->text();

if (table->item(i,3)->background().color()==Qt::red)

{

outlog<<incorrect;

openLog=true;

}

outlog<<"\r\n";

outlog.flush();

}

}

log.close();

}

//Конец записи лог-файла

QString notepadarg = "notepad "+logpath;

if(hiding)

{

if(openLog)

{

QProcess notepad;

notepad.startDetached(notepadarg);

}

} else

{

int header=0, firstcall=-1, size=table->rowCount(),

gotError, gotheader=-1; QColor error;

QString info (" - обнаружены ошибки!");

error.setRgb(245,61,46);

gotError=0;

int noError=1, gotHeader=0;

for (int i=0; i<size; ++i)

{

if (!size) break;

if(table->item(i,0)->background().color()==Qt::yellow)

{

table->item(i,0)->setBackground(Qt::green);

header=i;

continue;

}

if (table->item(i,2))

{

if(table->item(i,2)->text()!=" ")

if (table->item(i,2)->text()==table->item(i,3)->text())

do

{

table->removeRow(i);

--i;

--size;

if (table->item(i,2)&&table->item(i,2)->background().color()==Qt::red)

break;

else if (table->item(i,0)->background().color()==Qt::green)

break; else;

}

while (1);

else if(header!=gotheader)

{

table->item(header,0)->setBackground(error);

table->item(header,0)->setText(table->item(header,0)->text()+info);

gotheader=header;

}else;

}

else if (table->item(i,0)->background().color()==Qt::lightGray)

{

do

{

table->removeRow(i);

--i;

--size;

noError=1;

if (table->item(i,2)&&table->item(i,2)->background().color()==Qt::red)

break;

else if (table->item(i,0)->background().color()==Qt::green)

break;

}

while (1);

}

}

}

}

emit timeToCloseBars ();

emit lockStartButton (true);

emit unlockStopButton (false);

emit finished ();

}

signals:

void lockStartButton (bool);

void unlockStopButton (bool);

void lockStepChooser (bool);

void finished ();

void currentTable (QString);

void currentCommand (QString);

void gProgressValue (int);

void cProgressValue (int);

void timeToCloseBars ();

public slots:

void setTableCount (int a)

{

CountOfTestTables=a;

}

void setHiding (bool a)

{

hiding = a;

}

};

/************************************************************************

ПАРСЕР XML-ТАБЛИЦ

************************************************************************/

#pragma once

#include <QXmlStreamReader>

#include <QFile.h>

#include <QTableWidget.h>

#include <QMessageBox.h>

#include <QDir.h>

#include <QCoreApplication.h>

class XmlParser

{

private:

QXmlStreamReader Parser;

QTableWidget *TableWidget;

public:

XmlParser ()

{

}

QString GetTableName (QString &filePath)

{

QString NoName ("Файл не содержит имени");

QFile file(filePath);

file.open(QFile::ReadOnly | QFile::Text);

Parser.setDevice(&file);

while (!(Parser.atEnd()))

{

if (Parser.name()=="TableName")

{

Parser.readNext();

file.close();

return Parser.text().toString();

}

Parser.readNext();

}

file.close();

return NoName;

}

void GetTableList (QTableWidget *table)

{

QString ApplicationPath = QCoreApplication::applicationDirPath();

QDir TablesDir (ApplicationPath);

QStringList NamesOfTables, filter;

filter<<"*.xml";

TablesDir.setNameFilters(filter);

NamesOfTables=TablesDir.entryList();

for (int i=0; i<NamesOfTables.size(); ++i)

{

table->insertRow(i);

QString currentPath = ApplicationPath+'/'+NamesOfTables.at(i);

QTableWidgetItem *tableName = new QTableWidgetItem (GetTableName(currentPath));

QTableWidgetItem *tablePath = new QTableWidgetItem (currentPath);

table->setItem(i,0,tableName);

table->setItem(i,1,tablePath);

}

}

int GetData (const QString filePath, QTableWidget *TableWidget, int startPosition=-1)

{

QFile file(filePath);

file.open(QFile::ReadOnly | QFile::Text);

Parser.setDevice(&file);

Parser.readNext();

int rowCount=startPosition;

int rowsToSpan=0; int rowFromSpan=-1;

bool gotBack=false;

while (!(Parser.atEnd()))

{

if ((Parser.name()==("CommandName") ||

Parser.name()==("Call") ||

Parser.name()==("Back") ||

Parser.name()==("Delay") ||

Parser.name()==("Unit")))

{

if (Parser.name()=="CommandName")

{

TableWidget->insertRow(++rowCount);

Parser.readNext();

QTableWidgetItem *currentItem = new QTableWidgetItem (Parser.text().toString());

TableWidget->setItem (rowCount,0,currentItem);

if (Parser.name()=="Call")

{

Parser.readNext();

QTableWidgetItem *currentItem = new QTableWidgetItem (Parser.text().toString());

currentItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

TableWidget->setItem (rowCount,1,currentItem);

++rowsToSpan;

if(rowFromSpan==-1) rowFromSpan=rowCount; //Запоминается ради дальнейшего заполнения пустых ячеек

} //фоном (см. ниже)

if (Parser.name()=="Delay")

{

Parser.readNext();

QTableWidgetItem *currentItem = new QTableWidgetItem (Parser.text().toString());

TableWidget->setItem (rowCount,4,currentItem);

}

if (Parser.name()=="Back")

{

TableWidget->insertRow(++rowCount);

Parser.readNext();

QTableWidgetItem *currentItem = new QTableWidgetItem (Parser.text().toString());

currentItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

TableWidget->setItem (rowCount,2,currentItem);

QTableWidgetItem *forBrushing = new QTableWidgetItem(" "); TableWidget->setItem(rowCount,0,forBrushing);

TableWidget->item(rowCount,0)->setBackground(Qt::lightGray);

TableWidget->setSpan(rowCount,0,1,2);

gotBack=true;

QTableWidgetItem *emptyItem = new QTableWidgetItem (" ");

TableWidget->setItem (rowCount,3,emptyItem);

}

if (Parser.isEndElement()&&Parser.name()=="Unit") { //Оформление таблицы

if(gotBack)

{

QTableWidgetItem *forBrushing = new QTableWidgetItem(" "); TableWidget->setItem(rowCount,0,forBrushing);

TableWidget->item(rowCount,0)->setBackground(Qt::lightGray); TableWidget->setSpan(rowCount,0,1,2); gotBack=false; }

else

{

TableWidget->insertRow(++rowCount);

QTableWidgetItem *forBrushing = new QTableWidgetItem(" "); TableWidget->setItem(rowCount,0,forBrushing);

TableWidget->item(rowCount,0)->setBackground(Qt::lightGray);

TableWidget->setSpan(rowCount,0,1,4); gotBack=false;

}

QTableWidgetItem *forBrushing = new QTableWidgetItem(" ");

TableWidget->setItem(rowFromSpan,2,forBrushing);

TableWidget->item(rowFromSpan,2)->setBackground(Qt::lightGray);

TableWidget->setSpan(rowFromSpan,2,rowsToSpan,2);

rowsToSpan=0; rowFromSpan=-1;

//Конец оформления

}

Parser.readNext(); //Считать закрывающий тэг (прим. </CommandName>)

}

Parser.readNext(); //Считать следующий открывающий тэг (прим.

//<Call>)

}

TableWidget->hideColumn(4); //Спрятать столбец задержек

file.close();

return TableWidget->rowCount();

}

};

ПРИЛОЖЕНИЕ Б

(обязательное)

Результаты выполнения программы

Работа программы показана на рисунках Б.1, Б.2, Б.3, Б.4.

Рисунок Б.1 – Ручной режим, выполнение тестов всей таблицы

Рисунок Б.2 – Ручной режим, ход пошаговой проверки таблицы

Рисунок Б.3 – Автоматический режим, успешное прохождение всех тестов

Рисунок Б.4 – Автоматический режим, наличие неверных ответов