目錄名字
Qt 2D painting Demo 的翻譯
2D Painting 示例簡介:
該示例描述了怎樣使用QPainter 和QGLWidget 來顯示2D圖像。
QPainter類是實現2D圖形的繪製。
QGLWidget類可以實現圖形的加速,如果硬件支持的話。
該示例分別用兩種方式來實現繪製,一個是在QWiget抗鋸齒的方式繪製,另一個是在QGLWidget上抗鋸齒的方式繪製。
爲了能夠比較這兩種方式繪圖的結果,我們單獨創建一個Help 類供使用。
Helper Class 定義
在示例中,繪圖部分的功能是通過Help類來實現,該類非常簡短。
class Helper
{
public:
Helper();
public:
void paint(QPainter *painter, QPaintEvent *event, int elapsed);
private:
QBrush background;
QBrush circleBrush;
QFont textFont;
QPen circlePen;
QPen textPen;
};
除了構造函數,這裏只有一個paint()函數共widget的子類調用。
Helper Class 的實現
該類的構造函數,初始化了繪圖所需要的一些參數資源。
Helper::Helper()
{
QLinearGradient gradient(QPointF(50, -20), QPointF(80, 20));
gradient.setColorAt(0.0, Qt::white);
gradient.setColorAt(1.0, QColor(0xa6, 0xce, 0x39));
background = QBrush(QColor(64, 32, 64));
circleBrush = QBrush(gradient);
circlePen = QPen(Qt::black);
circlePen.setWidth(1);
textPen = QPen(Qt::white);
textFont.setPixelSize(50);
}
繪圖的操作是通過paint()函數。通常的做法是:
1、創建QPainter 的一個對象,將圖繪製到QWidget或者QGLWidget 上;
2、QPaintEvent提供了一個可供繪製的區域。,一個elapsed time用來描述了界面刷新的時間間隔。
void Helper::paint(QPainter *painter, QPaintEvent *event, int elapsed)
{
painter->fillRect(event->rect(), background);
painter->translate(100, 100);
我們一開始填充了一個背景,然後平移座標系到繪圖設備的中心(這裏圖的大小是200x200)進行下面的繪製。
我們繪製一個螺旋形的一些圓。通過參數elapset time 來繪製從座標原點向外逐漸外移的圓。
painter->save();
painter->setBrush(circleBrush);
painter->setPen(circlePen);
painter->rotate(elapsed * 0.030);
qreal r = elapsed / 1000.0;
int n = 30;
for (int i = 0; i < n; ++i) {
painter->rotate(30);
qreal factor = (i + r) / n;
qreal radius = 0 + 120.0 * factor;
qreal circleRadius = 1 + factor * 20;
painter->drawEllipse(QRectF(radius, -circleRadius,
circleRadius * 2, circleRadius * 2));
}
painter->restore();
由於這裏座標系統經過多次旋轉變換,這裏我們用到save() 和restore() 的方法 來回到變換之前的座標系。
painter->setPen(textPen);
painter->setFont(textFont);
painter->drawText(QRect(-50, -50, 100, 100), Qt::AlignCenter, QStringLiteral("Qt"));
}
最後我們在座標系的中心繪製文字“Qt”。
Widget Class 定義
該類個性化了窗體的顯示,通過調用Help類的繪製來實現動畫的功能。
class Helper;
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(Helper *helper, QWidget *parent);
public slots:
void animate();
protected:
void paintEvent(QPaintEvent *event) override;
private:
Helper *helper;
int elapsed;
};
可以看到,除了構造函數外,這裏包含了:
一個paintEvent() 函數,該函數使我們能後自定義圖形的繪製。
一個槽函數animate() 來實現動畫。
一個成員指針變量,指向Help類的成員對象。
一個記錄刷新時間的變量
Widget Class 實現
構造函數:
1、建立並保存一個helper對象;
2、將刷新時間設爲0;
3、將窗體大小設爲200x200
Widget::Widget(Helper *helper, QWidget *parent)
: QWidget(parent), helper(helper)
{
elapsed = 0;
setFixedSize(200, 200);
}
The animate() 槽函數實現了定時刷新界面的功能
void Widget::animate()
{
elapsed = (elapsed + qobject_cast<QTimer*>(sender())->interval()) % 1000;
update();
}
這裏我們,這裏我們決定了一個elapsed時間變化的快慢的處理方法。
通過paintEvent 事件來繪圖。
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter;
painter.begin(this);
painter.setRenderHint(QPainter::Antialiasing);
helper->paint(&painter, event, elapsed);
painter.end();
}
GLWidget Class 定義
GLWIDget類與widget類定義類似,唯一不同點是它繼承自QOpenGLWidget.
class Helper;
class GLWidget : public QOpenGLWidget
{
Q_OBJECT
public:
GLWidget(Helper *helper, QWidget *parent);
public slots:
void animate();
protected:
void paintEvent(QPaintEvent *event) override;
private:
Helper *helper;
int elapsed;
};
GLWidget Class 實現
構造函數:
GLWidget::GLWidget(Helper *helper, QWidget *parent)
: QOpenGLWidget(parent), helper(helper)
{
elapsed = 0;
setFixedSize(200, 200);
setAutoFillBackground(false);
}
animate() 槽函數與 Widget 類中雷同:
void GLWidget::animate()
{
elapsed = (elapsed + qobject_cast<QTimer*>(sender())->interval()) % 1000;
update();
}
paintEvent() 與與 Widget 類中雷同:
void GLWidget::paintEvent(QPaintEvent *event)
{
QPainter painter;
painter.begin(this);
painter.setRenderHint(QPainter::Antialiasing);
helper->paint(&painter, event, elapsed);
painter.end();
}
Window Class 定義
The Window class has a basic, minimal definition:
class Window : public QWidget
{
Q_OBJECT
public:
Window();
private:
Helper helper;
};
Window Class 實現
構造函數做了所有的工作,創建窗體和控件、創建一個定時器,
沒過50ms 會 update(),從而回調paintEvent函數,從而實現20幀每秒的刷新率
Window::Window()
{
setWindowTitle(tr("2D Painting on Native and OpenGL Widgets"));
Widget *native = new Widget(&helper, this);
GLWidget *openGL = new GLWidget(&helper, this);
QLabel *nativeLabel = new QLabel(tr("Native"));
nativeLabel->setAlignment(Qt::AlignHCenter);
QLabel *openGLLabel = new QLabel(tr("OpenGL"));
openGLLabel->setAlignment(Qt::AlignHCenter);
QGridLayout *layout = new QGridLayout;
layout->addWidget(native, 0, 0);
layout->addWidget(openGL, 0, 1);
layout->addWidget(nativeLabel, 1, 0);
layout->addWidget(openGLLabel, 1, 1);
setLayout(layout);
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, native, &Widget::animate);
connect(timer, &QTimer::timeout, openGL, &GLWidget::animate);
timer->start(50);
}
本篇翻譯完畢,本人翻譯純粹是項目應用和學習的需要,如有不妥,懇請朵朵指正。