Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Laboratornyy_praktikum_po_programmirovaniyu_v_s...doc
Скачиваний:
5
Добавлен:
01.03.2025
Размер:
1 Мб
Скачать
☆

Задания для самостоятельного выполнения

  1. Создайте приложение, которое позволяет рисовать отрезки пря­мых линий с помощью мыши. Создаваемая линия должна быть видима в процессе пос­тро­ения. Цвет линий должен определяться с помощью немодаль­но­го диало­го­вого окна с наборными счетчиками (Spin), которые позволяют установить интен­сив­ности красной, зеленой и синей составляющих цвета. Предоставьте воз­мож­ность сохранять изоб­ра­же­ние в файле и считывать его из файла.

  2. Создайте приложение, которое позволяет рисовать закра­шен­ные пря­мо­у­голь­ники с помощью мыши. Создаваемый прямоугольник должен быть видим в про­цессе пост­ро­ения. Цвет прямоугольников должен определяться с по­мо­щью немо­даль­но­го диало­го­вого окна с наборными счет­чиками (Spin), которые позволяют устано­вить интен­сивности красной, зеленой и синей составляющих цвета. Предоставьте воз­мож­ность сохранять изображе­ние в файле и считывать его из файла.

  3. Создайте приложение, которое позволяет рисовать закра­шенные тре­угольники, за­даваемые тремя щелчками мыши в вершинах. Цвет треугольников должен опре­де­ляться с помощью немодального диало­го­вого окна с наборными счет­чиками (Spin), которые поз­воляют установить интен­сивности красной, зеленой и синей состав­ляющих цвета. Пре­доставьте воз­мож­ность сохранять изображение в файле и считывать его из файла.

  4. Создайте приложение, которое позволяет рисовать закра­шен­ные кру­ги с по­мощью мыши. Создаваемая окружность должна быть ви­дима в процессе пос­тро­ения. Цвет окружностей должен определяться с по­мо­щью немодального диало­го­вого окна с наборными счетчиками (Spin), которые позволяют ус­та­новить интен­сивности красной, зеленой и синей состав­ляющих цвета. Предоставьте воз­мож­ность сохранять изобра­же­ние в файле и считывать его из файла.

  5. Создайте приложение, которое рисует закрашенные пяти­конечные звезды (впи­санную в воображаемую окружность; центр окруж­нос­ти и одна точка на окружности задаются щелчками мыши). Цвет каждой звез­дочки должен опре­деляться с помощью не­мо­дального диало­го­вого окна с на­борными счетчиками (Spin), которые поз­во­ля­ют установить интен­сивности красной, зеленой и синей составляющих цвета. Пре­доставьте воз­мож­ность сохранять изображение в файле и считывать его из файла.

  6. Создайте приложение, которое рисует закрашенные квад­раты с по­мощью мыши так, что мышь проходит по диагонали квадрата от од­ной вершины к дру­гой. Квадрат должен быть виден в процессе построения. Цвет линий дол­жен опре­делять­ся с помощью немо­дального ди­ало­го­вого окна с наборными счетчиками (Spin), которые позволяют устан­о­вить интен­сивности красной, зеленой и синей составляющих цвета. Предоставьте воз­мож­ность сохранять изоб­ра­же­ние в файле и считывать его из файла.

  7. Создайте приложение, которое рисует дуги с помощью мы­ши так, что мышь определяет начало и конец дуги. Дуга должен быть видима в процессе пос­тро­ения. Цвет линий должен определяться с помощью немо­даль­ного ди­ало­го­вого окна с набор­ными счетчиками (Spin), которые позволяют устан­о­вить интен­сивности красной, зеле­ной и синей составляющих цвета. Предоставьте воз­мож­ность сохранять изоб­ра­же­ние в файле и считывать его из файла.

  8. Создайте приложение, которое рисует правильные треу­голь­ники с по­мощью мыши так, что указатель мыши находится в одной из вершин треугольника. Тре­угольник должен быть видим в процессе пос­тро­ения и может поворачи­ваться. Цвет линий должен опре­де­ляться с помощью немо­дального ди­ало­го­вого окна с наборными счетчиками (Spin), которые поз­воляют устан­о­вить ин­тен­сивности красной, зеленой и синей составляющих цвета. При отпускании мыши треугольник закрашивается. Предоставьте воз­мож­ность сохранять изоб­ра­же­ние в файле и считывать его из файла.

  9. Создайте приложение, которое рисует правильные 8-ко­неч­ные звез­доч­ки с по­мощью мыши так, что указатель мыши находится в одной из вершин звез­доч­ки. Звездочка должна быть видима в процессе по­строения и может пово­рачи­ваться. При отпускании мыши звездочка закра­шивается. Цвет линий должен опре­де­ляться с по­мо­щью немо­дального ди­ало­го­вого окна с набор­ны­ми счетчиками (Spin), ко­торые поз­во­ляют устан­о­вить интен­сивности крас­ной, зеле­ной и синей составляющих цве­та. Предоставьте воз­мож­ность сохранять изоб­ра­же­ние в файле и считывать его из файла.

  10. Создайте однодокументное приложение, которое рисует правильные 5-ко­неч­ные звез­доч­ки с по­мощью мыши так, что указатель мыши находится в одной из вершин звез­доч­ки. Звездочка должна быть видима в процессе по­с­троения и может поворачиваться. Цвет линий должен опре­де­ляться с помощью немо­дального ди­ало­го­вого окна с набор­ными счетчиками (Spin), ко­торые поз­воляют устан­о­вить интен­сивности красной, зе­ле­ной и синей составляющих цве­та. Предоставьте воз­мож­ность сохранять изоб­ра­же­ние в файле и считывать его из файла.

  11. Создайте однодокументное приложение, которое рисует правильные шести­угольники с по­мощью мыши так, что указатель мыши находится в одной из вершин шестиугольни­ка. Шестиугольник должен быть видим в процессе пос­троения и может поворачиваться. Цвет линий должен опре­де­ляться с помощью немо­дального ди­ало­го­вого окна с набор­ными счетчиками (Spin), ко­торые поз­воляют устан­о­вить интен­сивности красной, зеленой и синей составляющих цве­та. Предоставьте воз­мож­ность сохранять изоб­ра­же­ние в файле и считывать его из файла..

Лабораторная работа № 8

Тема: «Области отсечения»

Пример 1: программа, которая рисует 6-угольник, цвет которого можно изменять с помощью немодального диалогового окна с на­бор­ными счетчиками (Spin). Диалоговое окно появляется при нажатии кнопки «Диалог».

Создайте проект на базе главного окна.

Д обавьте дочернее диалоговое окно, описы­ваемое классом Dialog (выберите в меню Файл | Новый файл или проект... , в появившемся диа­логовом окне выберите Qt | Класс формы Qt De­signer).

Спроектируйте окно как показано на рисун­ке, добавив элемент spinBox.

В файл main.cpp добавьте подчеркнутую строку:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow w;
    w.move(400, 250); // перемещает окно к центру экрана
    w.show();
    return a.exec();
}

В файлe dialog.h в описание класса добавьте подчеркнутые строки:

#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
    class Dialog;
}
class MainWindow; // С помощью этого класса объявим указатель на родительское окно
class Dialog : public QDialog
{
    Q_OBJECT
public:
// Измените тип указателя на MainWindow
    explicit Dialog(MainWindow *parent = 0); 

    ~Dialog();
    MainWindow* Parent; /* С помощью этого указателя диалоговое окно будет переда­вать новое значение цвета главному окну */
 //  объявление слота, который будет передавать новое значение цвета главному окну:
public slots:
    void setN(int);
private:
    Ui::Dialog *ui;
};
#endif // DIALOG_H

В файл dialog.cpp добавьте подчеркнутые строки:

#include "dialog.h"
#include "ui_dialog.h"
#include "mainwindow.h" 
 // обеспечивает возможность использования класса MainWindow
Dialog::Dialog(MainWindow *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    ui->spinBox->setRange(0, 255); 
 // Задаем диапазон изменнения значений наборного счетчика
   ui->spinBox->setSingleStep(5);  
// при щелчке по стрелочке значение счетчика будет изменяться на 5
   Parent = parent;  
// Указатель, объявленный в классе, становится равным значению локального указателя
   ui->spinBox->setValue(Parent->n); 
 /* Устанавливаем начальное значение счетчика так, чтобы оно было равно начальному значению цвета, установленного в конструкторе главного окна */
connect(ui->spinBox, SIGNAL(valueChanged(int)), 
this, SLOT(setN(int))); /* связываем сигнал об изменении значения счетчика со слотом, который передает новое значение цвета главному окну */ } Dialog::~Dialog() { delete ui; } void Dialog::setN(int n) /* значение n автоматически передается слоту от наборного счетчика с помощью сигнала valueChanged(int) { Parent->n = n; // передаем значение цвета переменной, объявленной в классе гланого окна Parent->update(); // посылаем сигнал «перерисовать окно» }

Добавьте в файл mainwindow.h подчеркнутые строки:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "dialog.h"  // Обеспечивает возможность использования класса Dialog
#include <QtGui> // обеспечивает возможность использования графических функций
namespace Ui {
    class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void paintEvent(QPaintEvent *);
 // функция, которая автоматически вызывается при перерисовывании окна
    Dialog* dlg; // объект, описывающий диалоговое окно
   int n; // значение яркости цвета
private:
    Ui::MainWindow *ui;
private slots:
    void on_actionDialog_triggered();
};
#endif // MAINWINDOW_H

В режиме проектирования формы с помощью редактора действий добавьте действие actionDialog с текстом «Диалог» (это будет командой меню, которая вы­зы­вает вспомогатель­ное диалоговое окно).

В файл mainwindow.cpp добавьте код, показанный ниже:

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    n = 100;  // начальное значение цвета
    dlg = new Dialog(this);  // создаем объект класса Dialog
    ui->menuBar->addAction(ui->actionDialog); 
 //  В меню создаем кнопку, соответствующую команде «Диалог» (без выпадающего меню)
}
MainWindow::~MainWindow()
{
    delete ui;
}
 // В режиме проектирования формы добавьте слот для действия actionDialg:
void MainWindow::on_actionDialog_triggered()
{
    dlg->move(400+width(), 250);
 // размещаем диалоговое окно на правой границе главного окна
    dlg->show(); // рисуем окно на экране
    dlg->activateWindow(); // делаем диалоговое окно активным
}
// Описываем, что нужно нарисовать в окне
void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);// Объект для рисования
    QString str = QString::number(n);/* Строка, с помощью которой на экране будет отоб­ражаться текущая яркость цвета */
    painter.drawText(20,70, str);// Отображаем на экране значение яркости цвета
    QBrush brush(QColor(n,0,0));/* объявляем кисть, число n в данном случае будет опре­елять яркость красного цвета */
    painter.setBrush(brush);// побключаем кисть
    QPolygonF polygon; // Объявляем многоугольник 
    qreal r = 100; // радиус окружности, в которую будет вписан многоугольник 
    qreal x0 = 200, y0 = 150; // центр окружности 
    qreal dfi =  M_PI / 3; // угол между вершинами 6-угольника
    for (int i = 0; i< 6; ++i) // рисуем 6-угольник
    {
        qreal fi = dfi * i; // угол, соответствующий очередной вершине
// определяем координаты вершины
        qreal x = x0 + r*cos(fi);
        qreal y = y0 + r*sin(fi);
        polygon << QPointF(x,y);// добавляем координаты вершины к полигону
    }
    painter.drawPolygon(polygon);// рисуем многоугольник (6-угольник)
}

Пример 2: программа, которая расчерчивает окно правильными 6-угольниками («пчелиными сотами»); размер шестиугольника — 1 / 5 меньшей стороны окна (но не меньше 2); при щелчке мышью внутри шестиугольника, он закрашивается цветом, выбранным с помощью специального окна для выбора цвета.

Создайте приложение на базе главного окна. В файле mainwindow.h добавьте объявления как показано ниже.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#define maxR 500 // максимальное количество строк
#define maxC 700 // максимальное количество столбцов
namespace Ui {
    class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void paintEvent(QPaintEvent *); 
// автоматически вызывается при перерисовке окна 
    void createMatrices(); 
// функция, размещающая в памяти матрицы полигонов и регионов
    void createNet(); // формирование сетки в рабочей области окна
    void createPolygon(int, int); // создание одной ячейки с заданными номерами
   void  mousePressEvent(QMouseEvent *);
 // автоматически вызыватся при щелчке мышью
   void resizeEvent(QResizeEvent *); 
// автоматически вызывается при создании окни и при изменении его размеров
    QPolygon** Polygon; // Указатель на матрицу полигонов
    QRegion** Region; // Указатель на матрицу областей
    QColor Color[maxR][maxC]; /* матрица для хранения цвета в каждой ячейке, она должна быть максимальных размеров, поскольку мы заранее не знаем размеры окна */
    int previousRows, rows, columns; /* количество строк для предыдущего состояния окна, текущее количество строк, количество столбцов */
    double w, h; // размеры рабочего поля
    double size, x0, y0, r; // размер одной ячейки, центр и радиус окружности, в которую вписан многоугольник
    QBrush brush; // кисть
private:
    Ui::MainWindow *ui;
private slots:
    void on_actionOpen_triggered();
    void on_actionSave_triggered();
};
#endif // MAINWINDOW_H

В файле mainwindow.cpp напишите код, показанный ниже:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtGui>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    for (int i = 0; i < maxR; ++i) 
          for (int j = 0; j<maxC; ++j) 
              Color[i][j] = QColor(0, 100, 100); 
// Заполняем матрицу начальным цветом
    previousRows = rows = columns = 0; // начальные размеры сетки
}
MainWindow::~MainWindow()
{
    delete ui;
}
 // Виртуальная функция, которая вызывается при изменении размеров окна
void MainWindow::resizeEvent(QResizeEvent * )
{
    w = width(); // ширина рабочего поля
    y0 = centralWidget()->y(); // Верхняя граница клиентской области
    h = height() - y0; // высота рабочего поля
    size = qMin(w, h) / 5;
 // размер одной ячейки (расстояние между двумя противоположными вершинами)
    if (size<2) size = 2; 
// размер не может оказаться равным нулю, чтобы не произошло деление на ноль
     // qDebug() << "size = " << size;
    r = size/2; // радиус окружности, в которую вписана ячейка
    x0 = r * sqrt(3)/2; 
// расстояние от левой границы окна до центра первого 6-угольника (красная линия на рисунке)
/* длина стороны правильного 6-угольника = r, а расстояние между ценрами ячеек (вертикаль­ный катет светлого треугольника) = r+r/2 = 3*r / 2 */
rows = int(2*h/(3*r)) +2; // количество полных рядов равно частному от деления высоты рабочей области на расстояние между центрами ячеек; к этому количеству нужно добавить 2 — неполные ряды на верхней и нижней границах окна
    if (rows>maxR) rows = maxR; 
// но количество рядов не может превышать задданый максимум
     //  qDebug() << "rows = " << rows;
     columns = int(w / (r*sqrt(3)))+2;
/* расстояние между центрами окружностей по горизонтали = (r*sqrt(3)/2) * 2 = r*sqrt(3), количество столбцов равно частному от деления ширины окна на расстояние между рядами + 2  неполных ряда на левой и правой границе */
    if (columns>maxC) columns = maxC; 
// количество столбцов неможет превышать заданный максимум
     // qDebug() << "columns = " <<columns;
    createMatrices(); /* при каждом изменении размеров окна создаем новые матрицы ячеек и соответствующих им областей */
    createNet(); // заполняем матрицы данными
}




















void MainWindow::paintEvent(QPaintEvent * )
{
    QPainter painter(this);
 // рисуем многоугольники цветом, который записан в матрице цветов:
    for (int i = 0; i < rows; ++i)
          for (int j = 0; j < columns; ++j)
        {
            painter.setBrush(QBrush(Color[i][j]));
            painter.drawPolygon(Polygon[i][j]);
        }
}
 // размещаем матрицы в памяти:
void MainWindow::createMatrices()
{
    if (previousRows)
 // удаляем предидущие матрицы из памяти, если они ненулевого размера
    {
        for (int i = 0; i < previousRows; ++i) // освобождаем память по строкам
        {
            delete[] Polygon[i]; // освобождаем память, выделенную для данных
            delete[] Region[i];
        }
        delete Polygon;  // удаляем массивы указателей
        delete Region;
    }
    previousRows = rows; // запоминаем текущее количество строк
// создаем массивы указателей на строки данных: 
    Polygon = new QPolygon* [rows]; 
    Region = new QRegion* [rows]; 
//  захватываем память для строк данных:
    for (int i = 0; i < rows; ++i) 
    {
        Polygon[i] = new QPolygon[columns]; // для координат 6-угольников
        Region[i] = new QRegion[columns]; // для областей
    }
}
void MainWindow::createNet() // заполняем матрицы данными
{
    double dx = r*sqrt(3); // расстояние между центрами ячеек по горизонтали
    double dy = r*3 / 2; //  расстояние между центрами ячеек по вертикали
    for (int i = 0; i <rows; ++i) // проходим по строкам
    {
          for (int j = 0; j<columns; ++j) // проходим по одной строке
          {
              createPolygon(i, j); 
// создаем ячейку в i-ой строке и в j — м столбце (вызываем функцию)
              x0+=dx; // переходим в следующий столбец
          }
          y0 += dy; // переходим к следующей строке
          if (i % 2 == 0) x0 = 0; 
// начало следующего ряда, если текущая строка -  четная
          else x0 = r*sqrt(3)/2; // если текущая строка - нечетная 
      }
}
void MainWindow::createPolygon(int i, int j) // определяем координаты одной ячейки
{
    double x, y; // координаты вершин многоугольника
    double da = M_PI/3; // угол между вершинами 
    double angle = da/2; // начальный угол
    Polygon[i][j].clear(); // очищаем контейнер
  for (int k = 0; k<6; ++k) // определяем вершины 6-угольника
    { 
	// вычисляем координаты очередной вершины как точки на окружности
        x = x0 + r*cos(angle);
        y = y0 + r*sin(angle);
        Polygon[i][j] << QPoint(x,y); 
// добавляем координаты очередной точки к полигону
        angle += da; // переходим к следующей вершине
    }
    Region[i][j] = QRegion(Polygon[i][j]); 
// когда 6-угольник определен, создаем соответствующую область
}
 // Слот, обрабатывающий щелчки мышью:
void MainWindow::mousePressEvent(QMouseEvent * event)
{
    QPoint point = event->pos(); // координаты курсора мыши
   // проверяем, в какой регион (в какой 6-угольник) попадает курсор мыши 
	for (int i = 0; i<rows; ++i) // проходим по строкам матрицы
        for(int j = 0; j<columns; ++j) // по столбцам
            if (Region[i][j].contains(point)) // если курсор попадает в область
            {
                Color[i][j] = QColorDialog::getColor(); // выбираем цвет
                brush = QBrush(Color[i][j]); // создаем кисть
                update(Region[i][j]); // перерисовываем 6-угольник
                goto exit; // выходим из циклов
            }
exit: ;
}
 // слот для команды Save:
void MainWindow::on_actionSave_triggered()
{
 //  вызываем окно для выбора имени файла: 
QString fileName = QFileDialog::getSaveFileName(this, "Сохранить файл", QString(),
    QString("Файлы данных (*.dat);;Все файлы (*.*)") );
    QFile rezFile; // Результирующий файл
    if (!fileName.isEmpty()) // Если имя файла задано
    {
           rezFile.setFileName(fileName);
    // присваиваем физическое имя результирующему файлу
           rezFile.open(QIODevice::WriteOnly);
    // открываем сохраняемый файл
          QDataStream out(&rezFile);
/* создаем поток, связанный с файлом (запись файла обычно выполняется с помощью потока) */
 //   записываем матрицу цветов в файл:         
for (int i = 0; i < maxR; ++i)
               for (int j = 0; j<maxC; ++j)
                   out <<Color[i][j];  // записываем цвет ячейки с номерами i и j
           rezFile.close();
      }
}

 // Слот, обрабатывающий команду Open:
void MainWindow::on_actionOpen_triggered()
{
 //   вызываем окно для выбора имени файла:   
QString fileName = QFileDialog::getOpenFileName(
this,  //  указатель на родительское окно
"Открыть файл", // заголовок окна
QString(),   // выбор начинается с текущего каталога
QString("Файлы с данными (*.dat);;Все файлы (*.*)") );
// фильтры для списка файлов
if ( ! fileName.isEmpty())      // если имя файла выбрано
     {
         QFile file;
         file.setFileName(fileName);
// связываем объект file с физическим файлом
         file.open(QIODevice::ReadOnly);
         QDataStream in(&file); // поток для чтения данных
            for (int i = 0; i < maxR; ++i)
                for (int j = 0; j<maxC; ++j)
                    in >> Color[i][j]; // считываем цвет ячейки
            file.close();
        }
 /* Главное окно приложения автоматически перерисовывается при закрытии окна для выбора файла */
}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]