Создайте проект на основе класса 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
Вставьте в файл mainwindow.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();
}