Qt 2D painting Demo 的翻译

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

本篇翻译完毕,本人翻译纯粹是项目应用和学习的需要,如有不妥,恳请朵朵指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章