目录名字
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);
}
本篇翻译完毕,本人翻译纯粹是项目应用和学习的需要,如有不妥,恳请朵朵指正。