- •Міжрегіональна академія управління персоналом
- •2. Малювання в qт4
- •2.1 Типові елементи малюнку.
- •2.2. Інструменти та механізми малювання.
- •2.3. Графічні примітиви та їх відтворення.
- •QPainter painter(this);
- •3 Висновки
- •4. Література
- •4. Qt, the cross-platform application framework. Http://qt.Nokia.Com/downloads/
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::HorPattern);
painter.drawRect(10, 15, 90, 60);
painter.setBrush(Qt::VerPattern);
painter.drawRect(130, 15, 90, 60);
painter.setBrush(Qt::CrossPattern);
painter.drawRect(250, 15, 90, 60);
painter.setBrush(Qt::Dense7Pattern);
painter.drawRect(10, 105, 90, 60);
painter.setBrush(Qt::Dense6Pattern);
painter.drawRect(130, 105, 90, 60);
painter.setBrush(Qt::Dense5Pattern);
painter.drawRect(250, 105, 90, 60);
painter.setBrush(Qt::BDiagPattern);
painter.drawRect(10, 195, 90, 60);
painter.setBrush(Qt::FDiagPattern);
painter.drawRect(130, 195, 90, 60);
painter.setBrush(Qt::DiagCrossPattern);
painter.drawRect(250, 195, 90, 60);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Brushes window;
window.setWindowTitle(“Brushes”);
window.show();
return app.exec();
}
Для створення візерунку ми зв’язуємо з художником пензель з вибраним типом штриховки та область заштриховування за допомогою операторів
painter.setBrush(Qt::HorPattern);
painter.drawRect(10, 15, 90, 60);
Ми намалювали прямокутник з визначеним візерунком. Qt::HorPattern незмінно використовується для створення моделі горизонтальних ліній.
Малювання «бублика»
У наступному прикладі ми створимо «бублик», користуючись функціями малювання програмної бібліотеки Qt4.
#include <QApplication>
#include <QApplication>
#include <QPainter>
#include <QWidget>
Class Donut : public QWidget
{
public:
Donut(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *event);
};
Donut::Donut(QWidget *parent)
: QWidget(parent)
{
}
void Donut::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setPen(QPen(QBrush("#535353"), 0.5));
painter.setRenderHint(QPainter::Antialiasing);
int h = height();
int w = width();
painter.translate(QPoint(w/2, h/2));
for (qreal rot=0; rot < 360.0; rot+=5.0 ) {
painter.drawEllipse(-125, -40, 250, 80);
painter.rotate(5.0);
}
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Donut window;
window.setWindowTitle("Donut");
window.show();
return app.exec();
}
«Бублик» - це вдосконалена геометрична фігура, яка своїм зовнішнім виглядом нагадує відомий кулінарний виріб. Ми створили візерунок нама-лювавши сімдесят два повернутих еліпси.
painter.setRenderHint(QPainter::Antialiasing);
Наступні інструкції
int h = height();
int w = width();
painter.translate(QPoint(w/2, h/2));
пересувають початок координатної системи у середину вікна. Використовуючи значення за умовчуванням, формуємо початкову позицію (0,0). Іншими словами, початкова позиція для промальовування знаходиться у верхньому лівому куті вікна. Переміщуючи координатну систему, малювання стає набагато простішим.
for (qreal rot=0; rot < 360.0; rot+=5.0 ) {
painter.drawEllipse(-125, -40, 250, 80);
painter.rotate(5.0);
}
Цими інструкціями ми по колу малюємо сімдесят два еліпси.
Форми
Набір примітивів Qt4 дозволяє малювати різноманітні форми. Нижче наведен приклади деяких з них.
#include <QApplication>
#include <QPainter>
#include <QPainterPath>
#include <QWidget>
class Shapes : public QWidget
{
public:
Shapes(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *event);
};
Shapes::Shapes(QWidget *parent)
: QWidget(parent)
{
}
void Shapes::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(QBrush("#575555"), 1));
QPainterPath path1;
path1.moveTo(5, 5);
path1.cubicTo(40, 5, 50, 50, 99, 99);
path1.cubicTo(5, 99, 50, 50, 5, 5);
painter.drawPath(path1);
painter.drawPie(130, 20, 90, 60, 30*16, 120*16);
painter.drawChord(240, 30, 90, 60, 0, 16*180);
painter.drawRoundRect(20, 120, 80, 50);
QPolygon polygon;
polygon << QPoint(130, 140) << QPoint(180, 170)
<< QPoint(180, 140) << QPoint(220, 110)
<< QPoint(140, 100);
painter.drawPolygon(polygon);
painter.drawRect(250, 110, 60, 60);
QPointF baseline(20, 250);
QFont font("Georgia", 55);
QPainterPath path2;
path2.addText(baseline, font, "Q");
painter.drawPath(path2);
painter.drawEllipse(140, 200, 60, 60);
painter.drawEllipse(240, 200, 90, 60);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Shapes window;
window.setWindowTitle("Shapes");
window.show();
return app.exec();
}
Даний програмний код є прикладом малювання дев'яти різних форм, зображених на малюнку вище. Промальовування здійснюється за допомогою класу QPainterPath
QPainterPath path1;
path1.moveTo(5, 5);
path1.cubicTo(40, 5, 50, 50, 99, 99);
path1.cubicTo(5, 99, 50, 50, 5, 5);
painter.drawPath(path1);
QPainterPath є класом, який використовується для створення різних фігур. Ми використали його для створення кривої Безье.
painter.drawPie(130, 20, 90, 60, 30*16, 120*16);
painter.drawChord(240, 30, 90, 60, 0, 16*180);
painter.drawRoundRect(20, 120, 80, 50);
Наведений код малює диск, хорду та закруглений прямокутник.
Наступний фрагмент програми є вдповідальним за промальовування полігонів з пятьма вершинами.
QPolygon polygon;
polygon << QPoint(130, 140) << QPoint(180, 170)
<< QPoint(180, 140) << QPoint(220, 110)
<< QPoint(140, 100);
painter.drawPolygon(polygon);
Програмна бібліотека Qt4 може бути використана для створення траєкторії для графічного промальовування символів кодової таблиці.
QPointF baseline(20, 250);
QFont font("Georgia", 55);
QPainterPath path2;
path2.addText(baseline, font, "Q");
painter.drawPath(path2);
painter.drawEllipse(140, 200, 60, 60);
painter.drawEllipse(240, 200, 90, 60);
Метод drawEllipse() може бути використаний як для малювання еліпсів так і для малювання кіл. Дане коле це особливий випадок еліпсу.
Градієнтне забарвлення.
У комп’ютерній графіці, градієнт це поступовий перехід тіні з світлого кольору у темний або з одного кольору в інший. У 2D малюванні градієнт використовується для створення яскравого заднього плану та спецефектів так само як і для симуляції світла та тіні.
Приведений нижче приклад покаже, як створити градієнт за допомогою бібліотеки Qt4.
#include <QDesktopWidget>
#include <QApplication>
#include <QApplication>
#include <QPainter>
#include <QWidget>
class Gradient : public QWidget
{
public:
Gradient(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *event);
};
Gradient::Gradient(QWidget *parent)
: QWidget(parent)
{
}
void Gradient::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QLinearGradient grad1(0, 20, 0, 110);
grad1.setColorAt(0.1, Qt::black);
grad1.setColorAt(0.5, Qt::yellow);
grad1.setColorAt(0.9, Qt::black);
painter.fillRect(20, 20, 300, 90, grad1);
QLinearGradient grad2(0, 55, 250, 0);
grad2.setColorAt(0.2, Qt::black);
grad2.setColorAt(0.5, Qt::red);
grad2.setColorAt(0.8, Qt::black);
painter.fillRect(20, 140, 300, 100, grad2);
}
void center(QWidget &widget)
{
int x, y;
int screenWidth;
int screenHeight;
int WIDTH = 350;
int HEIGHT = 260;
QDesktopWidget *desktop = QApplication::desktop();
screenWidth = desktop->width();
screenHeight = desktop->height();
x = (screenWidth - WIDTH) / 2;
y = (screenHeight - HEIGHT) / 2;
widget.setGeometry(x, y, WIDTH, HEIGHT);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Gradient window;
window.setWindowTitle("Gradients");
window.show();
center(window);
return app.exec();
}
Даним кодом ми намалювали два прямокутники заповненими градієнтом.
QLinearGradient grad1(0, 20, 0, 110);
grad1.setColorAt(0.1, Qt::black);
grad1.setColorAt(0.5, Qt::yellow);
grad1.setColorAt(0.9, Qt::black);
Колір у градієнті визначається задаванням проміжних точок градієнт-ного переходу. Метод setColorAt() створює стартову точку точку з заданим кольором.
painter.fillRect(20, 20, 300, 90, grad1);
Ми заповнюємо прямокутник градієнтом.
Ефект «Пориву вітру»
У наступному прикладі ми створимо ефект «пориву вітру». Приклад покаже наростаючий розмір центрованого тексту, який поступово розчиняється у просторі полотна малювання. Це загальний ефект, який ви можете побачити у флеш анімації на веб-сторінках.
#include <QDesktopWidget>
#include <QApplication>
#include <QApplication>
#include <QPainter>
#include <QPainterPath>
#include <QTimer>
#include <iostream>
#include <QWidget>
class Puff : public QWidget
{
public:
Puff(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *event);
void timerEvent(QTimerEvent *event);
private:
int x;
qreal opacity;
int timerId;
};
Puff::Puff(QWidget *parent)
: QWidget(parent)
{
x = 1;
opacity = 1.0;
timerId = startTimer(15);
}
void Puff::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QString text = "ZetCode";
painter.setPen(QPen(QBrush("#575555"), 1));
QFont font("Courier", x, QFont::DemiBold);
QFontMetrics fm(font);
int textWidth = fm.width(text);
painter.setFont(font);
if (x > 10) {
opacity -= 0.01;
painter.setOpacity(opacity);
}
if (opacity <= 0) {
killTimer(timerId);
std::cout << "timer stopped" << std::endl;
}
int h = height();
int w = width();
painter.translate(QPoint(w/2, h/2));
painter.drawText(-textWidth/2, 0, text);
}
void Puff::timerEvent(QTimerEvent *event)
{
x += 1;
repaint();
}
void center(QWidget &widget)
{
int x, y;
int screenWidth;
int screenHeight;
int WIDTH = 350;
int HEIGHT = 280;
QDesktopWidget *desktop = QApplication::desktop();
screenWidth = desktop->width();
screenHeight = desktop->height();
x = (screenWidth - WIDTH) / 2;
y = (screenHeight - HEIGHT) / 2;
widget.setGeometry(x, y, WIDTH, HEIGHT);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Puff window;
window.setWindowTitle("Puff");
window.show();
center(window);
return app.exec();
}
Цілком зрозуміло, що цього ефекту можна досягти чередою кадрів напису, що появляється і зникає на полотні, збільшуючись у розмірах. Реалізувати його можна задіянням таймеру, який упорядковує процес промальовування та стиранням тексту:
Puff::Puff(QWidget *parent)
: QWidget(parent)
{
x = 1;
opacity = 1.0;
timerId = startTimer(15);
У конструкторі ми запускаємо таймер. Кожні 15 мілісекунд збуджується подія перемальовування.
void Puff::timerEvent(QTimerEvent *event)
{
x += 1;
repaint();}
Всередині функції із стандартним іменем timerEvent() ми збільшуємо розмір напису та перемальовуємо полотно.
if (x > 10) {
opacity -= 0.01;
painter.setOpacity(opacity);
}
Якщо початковий розмір більший ніж 10, ми поступово зменшуємо інтенсивність кольору літер. В кінці кінців, текст поступово стає невидимим ( розчиняється).
if (opacity <= 0) {
killTimer(timerId);
std::cout << "timer stopped" << std::endl;
}
Якщо текст повністю зникає, ми зупиняємо таймер.