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

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

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

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

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

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

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

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

Тема: «Работа с массивами с помощью класса QVector»

Пример: программа считывает массив неотрицательных чи­сел из файла, выводит его на экран, используя полосы прокрутки, и рисует круговую диаграмму для 13 самых больших элементов, ото­б­ражая остальные в сумме.

Создайте проект на базе главного окна. Добавьте класс Pole, производный от QWidget. В главном окне создадим область прокрутки и поместим в эту область по­ле, на котором выведем массив и отображающую его круговую диаграмму.

В меню главного окна добавьте меню File и действие Open.

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

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "pole.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QTextCodec* codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForCStrings(codec);
    QScrollArea* scroll = new QScrollArea(this); 
 // создаем область прокрутки
    Pole* pole = new Pole(scroll);  // создаем новый виджет
    scroll->setWidget(pole);  // размещаем виджет в области прокрутки
    setCentralWidget(scroll);  // делаем область прокрутки рабочей областью окна
    connect(ui->actionOpen, SIGNAL(triggered()), pole, SLOT(fileOpen()));  
// связываем вызов команды File|Open со слотом, который мы создадим в классе Pole
}
MainWindow::~MainWindow()
{
    delete ui;
}

В файл pole.h добавьте показанный ниже код.

#ifndef POLE_H
#define POLE_H
#include <QWidget>
#include <QtGui>
class Pole : public QWidget
{
    Q_OBJECT
public:
    explicit Pole(QScrollArea* parent = 0); 
// измените тип указателя на родительское окно
    QScrollArea* Parent; // указатель на область прокрутки
    void paintEvent(QPaintEvent *); // перерисовывает содержимое окна
    QFile file; // файл, содержащий массив
    QString fileName; // имя файла
    QVector<double> v; // массив
    QVector<double> copyV; // копия массива
    QFont font; // шрифт
    int dy; // расстояние между элементами массива при выводе на экран
    int k; // количество элементов массива
    void Pie(QPainter&, QRect&, int, int, int);
 // рисует один кусок диаграммы
signals:
public slots:
    void fileOpen(); // слот, считывающий массив из файла
};
#endif // POLE_H

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

#include "pole.h"
#include "mainwindow.h"
Pole::Pole(QScrollArea* parent) :   // измените тип указателя на родительское окно
    QWidget(parent)
{
    Parent = parent; // запоминаем значение указателя
}
void Pole::paintEvent(QPaintEvent *) // отображаем массив на экране:
{
    QPainter painter(this);
    int y = 20; // уровень, с которого начинается вывод массива на экран
    painter.setFont(font); // устанавливаем шрифт
    // Вывод массива:
    double sum = 0; // сумма элементтов массива
    k = v.size(); // размер массива
    for (int i = 0; i < k; ++i) // проходим по массиву
    {
        painter.drawText(10, y, QString::number(v[i])); 
// выводим очередной элемент массива на экран
        y += dy; // переходим на другую строку
        sum += v[i]; // добавляем элемент к сумме
    }
    copyV = v; 
// копируем массив, чтобы исходный массив отображался на экране без изменений
    qSort(copyV.begin(), copyV.end(), qGreater<double>());
 // сортируем копию массива по убыванию, чтобы построить диаграмму
    // Диаграмма:
    QRect rectBase = Parent->rect();
 // прямоугольник, соответствующий видимой части области прокрутки
    QRect rect = rectBase; // прямоугольник, в котором мы будем рисовать диаграмму
    int h = rectBase.height()-25; // несколько уменьшим высоту прямоугольника
    rect.setSize(QSize(h,h)); // задаем квадрат высотой h
    rect.moveRight(rectBase.width()-25); // перемещаем квадрат к правой границе окна
    double startAngle = 0; // начальный угол для первого фрагмента диаграммы
    double spanAngle = 0; // угол, 
    for (int i = 0; i < qMin(13, k); ++i) // 
    {
        spanAngle = 360 * 16.* copyV[i] / sum ; // Угол между радиусами
        Pie(painter, rect, startAngle, spanAngle, i); // 
        startAngle += spanAngle; // 
    }
    if (k > 13) // 
    {
        spanAngle = 360*16 - startAngle; // 
        Pie(painter, rect, startAngle, spanAngle, 13); // 
    }
}
void Pole::fileOpen()
{
    if (file.isOpen()) file.close();
    v.clear(); // 
    copyV.clear(); // 
    fileName = QFileDialog::getOpenFileName(this, "Открыть файл", QString(),
                                            QString("Текстовые файлы (*.txt);;Все файлы (*.*)")); // 
    if (!fileName.isEmpty()) // 
    {
        file.setFileName(fileName); // 
        file.open(QIODevice::ReadOnly); // 
        QTextStream in(&file); // 
        double x; // 
        while (true) // 
        {
            in >> x; // 
            if (x < 0) // 
            {
                QMessageBox::critical(this, "Ошибка в данных",
                                      "Все числа должны быть больше 0");
                return;
            }
            if (!in.atEnd()) // 
                v << x; // 
            else break; // 
        }
        font = QFont("Serif", 12); // 
        QFontMetrics fm(font); // 
        dy = fm.height(); // 
        k = v.size(); // 
        int height = qMax(1500, 20 + k*dy); // 
        this->resize(1500, height); // 
     }
}
void Pole::Pie(QPainter & painter,QRect& rect, int startAngle, int spanAngle, int i)
{ // 
        int c = i+1; // 
        int I, R,G,B; // 
        B = c % 2; c /= 2; // 
        G = c % 2; c /= 2; // 
        R = c % 2; c /= 2; // 
        I = c % 2; // 
        painter.setBrush(QBrush(QColor(I*100+R*155,I*100+G*155,I*100+B*155))); // 
        painter.drawPie(rect, startAngle, spanAngle); // 
}
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]