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

Пример 2: программа, в которой используется область отсечения qRegion и котекстное меню для выбора способа заливки этой области.

Создайте проект на основе класса QMainWindow. Добавьте в класс MainWindow (файл mainwindow.h) объявления данных и функций:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtGui> // обеспечивает программирование графического интерфейса
namespace Ui {
    class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void contextMenuEvent(QContextMenuEvent *event); 
// обрабатывет щелчок правой кнопкой мыши
    void paintEvent(QPaintEvent *); // перерисовывает окно
    QRegion region; // область отсечения
    QMenu* contextMenu; // указатель для создания контекстного меню
    QBrush brush; // кисть для закрашивания области отсечения
    qreal x, y; // начальная точка области рисования 
    qreal width, height; // ширина и высота области рисования
    qreal cx, cy; // координаты центра области рисования
    bool diagcross; // признак диагональной заливки
public slots:
    void Solid(); // для действия «Сплошная»
    void Semitransparent(); // «Полупрозрачная»
    void Gradient(); // «Градиентная»
    void DiagCross(); // «Сетка»
p
rivate:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

Вставьте в файл mainwin­dow.cpp определения функций как показано ниже:

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 // обеспечиваем использование кириллицы:
    QTextCodec* codec = QTextCodec::codecForName("Utf-8");
QtextCodec::setCodecForCStrings(codec);
contextMenu = new QMenu(this); // создаем контекстное меню
// Действия для контекстного меню:
QAction* actSolid = new QAction("Сплошная", this);
    contextMenu->addAction(actSolid);  
    connect(actSolid, SIGNAL(triggered()), this, SLOT(Solid()));  
    contextMenu->addSeparator();  
   QAction* actSemitransparent = new QAction("Полупрозрачная", this);
    contextMenu->addAction(actSemitransparent);
    connect(actSemitransparent, SIGNAL(triggered()), this, SLOT(Semitransparent()));
    contextMenu->addSeparator();
    QAction* actGradient = new QAction("Градиентная", this);
    contextMenu->addAction(actGradient);
    connect(actGradient, SIGNAL(triggered()), this, SLOT(Gradient()));
    contextMenu->addSeparator();
    QAction* actDiagcross = new QAction("Сетка", this);
    contextMenu->addAction(actDiagcross);
    connect(actDiagcross, SIGNAL(triggered()), this, SLOT(DiagCross()));
    brush = QBrush(Qt::darkGreen); // начальный цвет кисти
    diagcross = false; // в начале заливка - сплошная
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::paintEvent(QPaintEvent * e)
{
  QPainter painter(this);
  painter.setRenderHint(QPainter::Antialiasing); 
// установили режим сглаживания линий
 // Начальные координаты области рисования относительно главного окна: 
x = centralWidget()->x(); 
  y = centralWidget()->y();
  //qDebug() << x << y; // посмотрите значения этих координат
  width = centralWidget()->width(); // ширина области рисования
  height = centralWidget()->height(); // высота области рисования
// Координаты центра области рисования:  
cx = x + width/2; 
  cy = y + height/2;  
  qreal right = x+width; // координата правой границы области рисования
  qreal bottom = y+height; // координата нижней границы области рисования
 // Закрашиваем область рисования:
QColor color = QColor(200,150,100); 
  painter.setBrush(color); 
  QRectF rect(x,y,width, height);
  painter.drawRect(rect);
 // Отступы от границ для эллипса
qreal dx = width/10;
  qreal dy = height/10;
 // определяем область в виде эллипса:
  QRegion ellipticRgn = QRegion(x+dx, y+dy, width-2*dx, height-2*dy, QRegion::Ellipse);
 // Определяем многоугольник:
  QPolygon polygon;
 // Отступы от границ области рисования
  dx = width/20;
  dy = height/20;
 // Определяем вершины многоугольника:
  polygon << QPoint(x+dx, y+dy) << QPoint(cx, cy) << QPoint (right - dx, y+dy) << QPoint(right - dx, bottom-dy) << QPoint(cx,cy) << QPoint(x+dx, bottom-dy);
  QRegion polygonRgn(polygon); 
// Область отсечения в виде двух треугольников
  region = ellipticRgn.xored(polygonRgn); 
// Объединяем области с помощью оперции «исключающее или»
  painter.setClipRegion(region); // устанвливаем область отсечения
 // Если выбрана «Сетка»:
  if (diagcross) 
painter.fillRect(e->rect(),QBrush(Qt::green)); 
// заливаем фон области отсечения (это не обязательно) 
  painter.fillRect(e->rect(), brush); 
/* заливаем область отсечения выбранным способом (указываем весь прямоугольник окна, но закрашена будет только область отсечения) */
  painter.setClipping(false); // Отменяем установку области отсечения 
/* рисуем диагонали области рисования (для проверки, что она восстановлена, и для проверки, что фигура центрирована) */
  painter.drawLine(x,y,right, bottom);
  painter.drawLine(right,y, x, bottom );
}
 // Функция, которая выводит на экран 
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
    QPoint point = event->pos(); // определяем координаты курсора мыши
    if (region.contains(point)) 
// проверяем, щелкнули ли мы внутри области отсечения
    {
        contextMenu->exec(event->globalPos()); // выводим меню на экран
    }
}
 // Слот для команды «Сплошная»:
void MainWindow::Solid()
{
    brush = QBrush(Qt::darkGreen);
    diagcross = false;
    update();
}
 // Слот для команды «Полупрозрачная» :
void MainWindow::Semitransparent()
{
    QColor color(0, 128, 0, 100);
 // последний параметр определяет прозрачность (255 — не прозрачный)
    diagcross = false;
    brush = QBrush(color);
    update();
}
 // Слот для команды «Градиентная»:
void MainWindow::Gradient()
{
    QRadialGradient gradient(QPoint(cx, cy),width/2,QPoint(cx, cy));
 //  параметры: центральная точка, радиус и точка фокуса   
 // определяем цвета заливки, которые будут переходить друг в друга:
    gradient.setColorAt(0, Qt::yellow);
    QColor color(255, 100, 0);
    gradient.setColorAt(0.5, color);
    gradient.setColorAt(1, Qt::darkGreen);
    brush = QBrush(gradient); 
// устанавливаем кисть для градиентной заливки
    diagcross = false;
    update();
}
void MainWindow::DiagCross()
{
    brush = QBrush(Qt::darkGreen, Qt::DiagCrossPattern); 
// определяем кисть для заливки сеткой 
    diagcross = true; /* устанавливаем признак заливки сеткой (чтобы предварительно залить фон для сетки) */
    update();
}
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]