Пример 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(); // «Сетка»

private:

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();

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: