Добавил:
Факультет ИКСС, группа ИКВТ-61 Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
LAB / WORK_9 / лаб_раб_9.docx
Скачиваний:
35
Добавлен:
20.02.2019
Размер:
252.12 Кб
Скачать

ФЕДЕРАЛЬНОЕ АГЕНТСТВО СВЯЗИ

ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА»

(СПбГУТ)

Кафедра программной инженерии и вычислительной техники

Отчёт

по лабораторной работе №9 на тему: «Разработка кросс-платформенного приложения»

по дисциплине «Операционные системы»

Выполнил: студент группы ИКВТ-61, UКозырев А.Б.

« » 2018 г. ___________/А.Б. Козырев/

Принял: __к.т.н. Дагаев А.В.

« » 2018 г. ___________/_А.В. Дагаев/

Задание: разработать приложение с применением posix функций на кроссплатформенных языках программирования

Среда разработки приложения: Qt Creator 4.8.0

Разрабатываемое приложение основано на использовании Qt Widgets Application – среды для создания графического интерфейса.

Созданное приложение AppWidget управляет программой Euler.exe (исходный код и реализация в приложении)

Исходный код:

#include "appwidget.h"

#include "ui_appwidget.h"

#include <QProcess>

#include <QDebug>

#include <QStringList>

#include <QFile>

#include "windows.h"

QString method = "random";

QString algorithm = "normal";

AppWidget::AppWidget(QWidget *parent) :

QMainWindow(parent),

ui(new Ui::AppWidget)

{

ui->setupUi(this);

}

AppWidget::~AppWidget()

{

delete ui;

}

void AppWidget::on_start_explicit_clicked()

{

QProcess process;

QString program = "C:\\EulerApp\\release\\Euler.exe";

process.setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args)

{

args->flags |= CREATE_NEW_CONSOLE;

args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES;

});

process.start(program);

process.waitForFinished(-1);

process.close();

}

void AppWidget::on_choice_force_clicked(bool checked)

{

if (checked)

method = "random";

}

void AppWidget::on_choice_strategy_clicked(bool checked)

{

If (checked)

method = "strategy";

}

void AppWidget::on_choice_modified_clicked(bool checked)

{

If (checked)

algorithm = "modified";

}

void AppWidget::on_choice_normal_clicked(bool checked)

{

If (checked)

algorithm = "normal";

}

void AppWidget::on_start_inhibit_clicked()

{

QProcess process;

QString startingSquare = "no";

QString finalSquare = "no";

QStringList parameters;

QString inputStart = ui->start_square->text();

QString inputFinal = ui->final_square->text();

QString inputIterations = ui->repeat_count->text();

QString inputProbability = ui->given_probability->text();

if (inputStart.isEmpty() == FALSE)

startingSquare = "yes";

if (inputFinal.isEmpty() == FALSE)

finalSquare = "yes";

if (inputIterations.isEmpty() == TRUE)

inputIterations = "0";

if (inputProbability.isEmpty() == TRUE)

inputProbability = "0";

if (inputIterations.toInt() != 0 && ui->choice_iterate->isChecked())

{

inputProbability = "0";

ui->given_probability->clear();

}

else if (inputProbability.toDouble() != 0 && ui->choice_probability->isChecked())

{

inputIterations = "0";

ui->repeat_count->clear();

}

parameters << startingSquare << inputStart << finalSquare

<< inputFinal << method << algorithm << inputIterations << inputProbability;

QString program = "C:\\EulerApp\\release\\Euler.exe";

process.startDetached(program, parameters);

process.waitForFinished(-1);

process.close();

QFile inputFile("C:/EulerApp/release/report.txt");

if (!inputFile.open(QIODevice::ReadOnly))

{

qDebug() << "Ошибка открытия для чтения";

}

else

{

QTextStream in(&inputFile);

if (!in.atEnd() && ui->choice_iterate->isChecked())

{

QString line = in.readLine();

ui->result_probability->setText(line);

ui->result_count->clear();

inputFile.close();

}

else if (!in.atEnd() && ui->choice_probability->isChecked())

{

in.readLine();

QString line = in.readLine();

ui->result_count->setText(line);

ui->result_probability->clear();

inputFile.close();

}

}

}

void AppWidget::on_clear_button_clicked()

{

ui->start_square->clear();

ui->final_square->clear();

ui->repeat_count->clear();

ui->given_probability->clear();

ui->result_probability->clear();

ui->result_count->clear();

}

void AppWidget::on_choice_iterate_clicked(bool checked)

{

if (checked)

ui->given_probability->clear();

}

void AppWidget::on_choice_probability_clicked(bool checked)

{

if (checked)

ui->repeat_count->clear();

}

void AppWidget::on_close_window_clicked(bool checked)

{

if (checked)

this->close();

}

Для того, чтобы понять, как работает данное окно, следует обратиться к скриншоту:

В дизайнере формы окна выбирается каждый элемент, затем пишется код для организации его работы.

Предположим, пользователь нажимает на кнопку “DISPLAY APPLICATION”.

Тогда, управление переходит в тело слота on_start_explicit_clicked()

void AppWidget::on_start_explicit_clicked()

{

QProcess process;

QString program = "C:\\EulerApp\\release\\Euler.exe";

process.setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args)

{

args->flags |= CREATE_NEW_CONSOLE;

args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES;

});

process.start(program);

process.waitForFinished(-1);

process.close();

}

, и выполняется следующая последовательность действий.

  1. Создаётся новый процесс QProcess

  2. Указывается путь к исполняемой программе (Euler.exe)

  3. Вызывается модификатор аргументов нового процесса, который устанавливает дочерний процесс в самостоятельном окне

  4. Запускается дочерний процесс в своём консольном окне

  5. Родительский процесс ожидает завершения дочернего процесса (Euler.h)

  6. Дочерний процесс закрывается ещё раз для надёжности

В результате этих действий получается следующий результат:

Мы видим, что дочерний процесс начал работу в своём окне, стандартный вывод изолирован. Процесс родитель (окно формы) зависает до окончания работы дочернего процесса.

Предположим, пользователь выбирает конечное поле, задаёт требуемую вероятность, настраивает алгоритм работы программы Euler.exe, а затем нажимает на кнопку «START»

Тогда, управление переходит в тело слота для кнопки «START», а именно:

void AppWidget::on_start_inhibit_clicked()

{

QProcess process;

QString startingSquare = "no";

QString finalSquare = "no";

QStringList parameters;

QString inputStart = ui->start_square->text();

QString inputFinal = ui->final_square->text();

QString inputIterations = ui->repeat_count->text();

QString inputProbability = ui->given_probability->text();

if (inputStart.isEmpty() == FALSE)

startingSquare = "yes";

if (inputFinal.isEmpty() == FALSE)

finalSquare = "yes";

if (inputIterations.isEmpty() == TRUE)

inputIterations = "0";

if (inputProbability.isEmpty() == TRUE)

inputProbability = "0";

if (inputIterations.toInt() != 0 && ui->choice_iterate->isChecked())

{

inputProbability = "0";

ui->given_probability->clear();

}

else if (inputProbability.toDouble() != 0 && ui->choice_probability->isChecked())

{

inputIterations = "0";

ui->repeat_count->clear();

}

parameters << startingSquare << inputStart << finalSquare

<< inputFinal << method << algorithm << inputIterations << inputProbability;

QString program = "C:\\EulerApp\\release\\Euler.exe";

process.startDetached(program, parameters);

process.waitForFinished(-1);

process.close();

QFile inputFile("C:/EulerApp/release/report.txt");

if (!inputFile.open(QIODevice::ReadOnly))

{

qDebug() << "Ошибка открытия для чтения";

}

else

{

QTextStream in(&inputFile);

if (!in.atEnd() && ui->choice_iterate->isChecked())

{

QString line = in.readLine();

ui->result_probability->setText(line);

ui->result_count->clear();

inputFile.close();

}

else if (!in.atEnd() && ui->choice_probability->isChecked())

{

in.readLine();

QString line = in.readLine();

ui->result_count->setText(line);

ui->result_probability->clear();

inputFile.close();

}

}

}

, и выполняется следующая последовательность действий:

  1. Создаётся новый объект класса QProcess

  2. Начальное поле и конечное поле инициализируются на значение “no”, потому что пользователь может просто не ввести ничего в форму.

  3. Считываются все поля ввода через указатель на объекты формы Ui::AppWidget ui->[объект_формы]->text()

  4. Проверяются условия нулевых строк, устанавливаются ограничения на нелегальные случаи ввода.

  5. Создаётся список параметров для командной строки класса QString

  6. Указывается путь к исполняемой программе (Euler.exe)

  7. Запускается дочерний процесс в фоновом режиме с параметрами командной строки.

  8. Родительский процесс ожидает завершения дочернего

  9. Родительский процесс закрывает дочерний процесс и вмести с ним программу Euler.exe

  10. Родительский процесс открывает файл с результатом вычислений (вероятность, количество циклов), теми результатами, которые записываются в самой программе Euler.exe

  11. Родительский процесс начинает считывать результаты построчно через объект QTextStream in

  12. После чтения строки, указатель ui публикует результат в требуемое поле главной формы.

  13. Файл закрывается

В результате этих действий получается следующий результат:

Например, сколько нужно итераций для точности 0,9 если конечное поле а1?

Ответ: 49

Сколько нужно итераций для точности 0,99 , если конечно поле а1?

Ответ: 106

Какова вероятность того, что движок совершит полный маршрут заканчивая в поле с1, если количество итераций = 10000?

Ответ: 0,9672

Подробнее о программе Euler.exe в приложении.

При нажатии на кнопку “CLEAR” все поля очищаются от записей через указатель ui->[field_name]->clear();

При нажатии на кнопку “CLOSE” – основное окно AppWidget закрывается.

При нажатии на радио кнопку вызываются следующие слоты:

void AppWidget::on_choice_force_clicked(bool checked)

{

if (checked)

method = "random";

}

void AppWidget::on_choice_strategy_clicked(bool checked)

{

if (checked)

method = "strategy";

}

void AppWidget::on_choice_modified_clicked(bool checked)

{

if (checked)

algorithm = "modified";

}

void AppWidget::on_choice_normal_clicked(bool checked)

{

if (checked)

algorithm = "normal";

}

void AppWidget::on_choice_iterate_clicked(bool checked)

{

if (checked)

ui->given_probability->clear();

}

void AppWidget::on_choice_probability_clicked(bool checked)

{

if (checked)

ui->repeat_count->clear();

}

Все они нужны только для инициализации переменных method, algorithm и очищения содержимого полей.

Переменные method и algorithm передаются в командную строку, и они не могут быть нулевыми, иначе программа не сможет стартовать.

Соседние файлы в папке WORK_9