Qt 之圖形(繪製漂亮的圓弧)
阿新 • • 發佈:2020-08-17
簡述
綜合前面對二維繪圖的介紹,想必我們對一些基本繪圖有了深入的瞭解,下面我們來實現一些漂亮的圖形繪製。
圓形
經常地,我們會在網上看到一些列的抽獎活動,裡面就有圓盤抽獎,是不是有點手癢了O(∩_∩)O~
效果
原始碼
1 void MainWindow::paintEvent(QPaintEvent *)
2 {
3 QPainter painter(this);
4 painter.setRenderHint(QPainter::Antialiasing, true);
5
6 int radius = 150;
7 int arcHeight = 30;
8
9 // >> 1(右移1位)相當於width() / 2
10 painter.translate(width() >> 1, height() >> 1);
11
12 /**
13 * 引數二:半徑
14 * 引數三:開始的角度
15 * 引數四:指掃取的角度-順時針(360度 / 8 = 45度)
16 * 引數五:圓環的高度
17 * 引數六:填充色
18 **/
19 gradientArc(&painter, radius, 0 , 45, arcHeight, qRgb(200, 200, 0));
20 gradientArc(&painter, radius, 45, 45, arcHeight, qRgb(200, 0, 200));
21 gradientArc(&painter, radius, 90, 45, arcHeight, qRgb(0, 200, 200));
22 gradientArc(&painter, radius, 135, 45, arcHeight, qRgb(200, 0, 0));
23 gradientArc(&painter, radius, 225 , 45, arcHeight, qRgb(0, 200, 0));
24 gradientArc(&painter, radius, 180, 45, arcHeight, qRgb(0, 0, 200));
25 gradientArc(&painter, radius, 270, 45, arcHeight, qRgb(0, 0, 0));
26 gradientArc(&painter, radius, 315, 45, arcHeight, qRgb(150, 150, 150));
27 }
28
29 void MainWindow::gradientArc(QPainter *painter, int radius, int startAngle, int angleLength, int arcHeight, QRgb color)
30 {
31 // 漸變色
32 QRadialGradient gradient(0, 0, radius);
33 gradient.setColorAt(0, Qt::white);
34 gradient.setColorAt(1.0, color);
35 painter->setBrush(gradient);
36
37 // << 1(左移1位)相當於radius*2 即:150*2=300
38 //QRectF(-150, -150, 300, 300)
39 QRectF rect(-radius, -radius, radius << 1, radius << 1);
40 QPainterPath path;
41 path.arcTo(rect, startAngle, angleLength);
42
43 painter->setPen(Qt::NoPen);
44 painter->drawPath(path);
45 }
弧形
我們可以在之前的基礎上加一些處理,從而實現一個圓弧。
效果
原始碼
1 void MainWindow::gradientArc(QPainter *painter, int radius, int startAngle, int angleLength, int arcHeight, QRgb color)
2 {
3 // 漸變色
4 QRadialGradient gradient(0, 0, radius);
5 gradient.setColorAt(0, Qt::white);
6 gradient.setColorAt(1.0, color);
7 painter->setBrush(gradient);
8
9 // << 1(左移1位)相當於radius*2 即:150*2=300
10 //QRectF(-150, -150, 300, 300)
11 QRectF rect(-radius, -radius, radius << 1, radius << 1);
12 QPainterPath path;
13 path.arcTo(rect, startAngle, angleLength);
14
15 // QRectF(-120, -120, 240, 240)
16 QPainterPath subPath;
17 subPath.addEllipse(rect.adjusted(arcHeight, arcHeight, -arcHeight, -arcHeight));
18
19 // path為扇形 subPath為橢圓
20 path -= subPath;
21
22 painter->setPen(Qt::NoPen);
23 painter->drawPath(path);
24 }
這些只不過是我們實現的一個小效果,如果說你有什麼特殊的需要,可以在此基礎上進行擴充套件,比如:新增文字、動畫旋轉等。
文字
可以通過QPainterPath的addText()來新增文字。
效果
原始碼
1 void MainWindow::gradientArc(QPainter *painter, int radius, int startAngle, int angleLength, int arcHeight, QRgb color)
2 {
3 // 漸變色
4 QRadialGradient gradient(0, 0, radius);
5 gradient.setColorAt(0, Qt::white);
6 gradient.setColorAt(1.0, color);
7 painter->setBrush(gradient);
8
9 // << 1(左移1位)相當於radius*2 即:150*2=300
10 //QRectF(-150, -150, 300, 300)
11 QRectF rect(-radius, -radius, radius << 1, radius << 1);
12 QPainterPath path;
13 path.arcTo(rect, startAngle, angleLength);
14
15 // QRectF(-120, -120, 240, 240)
16 QPainterPath subPath;
17 subPath.addEllipse(rect.adjusted(arcHeight, arcHeight, -arcHeight, -arcHeight));
18
19 // path為扇形 subPath為橢圓
20 path -= subPath;
21
22 QFont font;
23 font.setFamily("Microsoft YaHei");
24 font.setPointSize(14);
25
26 painter->setPen(Qt::NoPen);
27 path.addText(path.pointAtPercent(0.5), font, QStringLiteral("一去丶二三裡"));
28 painter->drawPath(path);
29 }
旋轉
我們對前面的圓盤進行強化,新增一個旋轉效果。當然,常見的抽獎圓盤旋轉的是指標,而我們下面實現的是對圓盤的旋轉,如果你要實現一個抽獎轉盤,那麼可以再擴充套件。
效果
原始碼
1 // 利用定時器,定時變換角度,進行旋轉。
2 QTimer *pTimer = new QTimer(this);
3 pTimer->setInterval(100);
4 connect(pTimer, SIGNAL(timeout()), this, SLOT(updatePaint()));
5 pTimer->start();
6
7 // 改變角度,進行旋轉
8 void MainWindow::updatePaint()
9 {
10 m_nRotationAngle++;
11 if (m_nRotationAngle > 360)
12 m_nRotationAngle = 0;
13 update();
14 }
然後,只需要在繪圖事件中新增簡單的一行程式碼即可:
1 void MainWindow::paintEvent(QPaintEvent *)
2 {
3 ...
4 // 旋轉
5 painter.rotate(m_nRotationAngle);
6 ...
7 }