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

本篇翻譯完畢,本人翻譯純粹是項目應用和學習的需要,如有不妥,懇請朵朵指正。

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