Qt自定義控制元件之儀表盤3--雷達掃描圖
阿新 • • 發佈:2020-08-03
1、設計思想
雷達掃描圖,在影視作品中見到較多,比如飛機雷達、艦艇雷達,有一個掃描線轉圈代表雷達一週旋轉或一個批次的收發,發現目標就在錶盤上標記位置。和汽車儀表盤類似,汽車儀表盤有底盤背景圖、同圓、刻度、刻度值、旋轉的指標。能在汽車儀表盤的基礎上略作修改,比如指標換成帶有餘輝的掃描扇面,就能完成一個雷達掃描圖。
程式碼實現原理:
上圖的掃描線和餘輝效果,可以使用QConicalGradient 函式來實現,qconicalgradient()提供的是一種扇形漸變效果,圓錐式漸變或稱角度漸變。用這個漸變色來填充drawPie函式就可以實現扇形選擇的餘輝。
QConicalGradient::QConicalGradient(qreal cx
, qreal cy, qreal angle)void QPainter::drawPie(const QRectF &rectangle, int startAngle, int spanAngle)
Qt大神劉典武文章中有典型的講解,《Qt編寫自定義控制元件62-探探雷達》中實現的掃描效果就是雷達的效果。詳情移步https://zhuanlan.zhihu.com/p/85512788。
2、程式碼實現
繪製同心圓,x和y軸實線,45度對角線虛線。
void Radar::drawCircle(QPainter *painter) { painter->save(); QColor color = QColor(0, 100, 0); QPen pen = QPen(color, 2); painter->setPen(pen); for(int i=0; i<4; i++) { int r = this->radius / 4 * (i+1); painter->drawEllipse(-r, -r, r * 2, r * 2); } for(int i=0; i<=4; i++) // x,y 軸線是實線 { int r = this->radius; if((i%2) == 0) { pen.setStyle(Qt::SolidLine); } else{ pen.setStyle(Qt::DashDotLine); //pen.setDashPattern(QVector<qreal>() << 10 << 2 ); //實線:空線的比例 } painter->setPen(pen); painter->drawLine(-r, 0, r, 0); painter->rotate(90/2); } painter->restore(); }
繪製掃描圖,依靠錐形漸變顏色,通過透明度控制形成掃描效果,然後繪製餅圖。
void Radar::drawScan(QPainter *painter) { painter->save(); //錐形漸變顏色,通過透明度控制形成掃描效果 QConicalGradient conicalGradient(0, 0, this->angle); QColor color = QColor(0,150,0); color.setAlpha(100); conicalGradient.setColorAt(0, color); color.setAlpha(20); conicalGradient.setColorAt(0.1, color); color.setAlpha(0); conicalGradient.setColorAt(1, color); //繪製餅圓 QPen pen; pen.setWidth(5); pen.setBrush(conicalGradient); painter->setPen(pen); painter->setBrush(conicalGradient); int r = this->radius; QRect rect(-r, -r, r * 2, r * 2); painter->drawPie(rect, this->angle * 16, 360 * 16); // 1/16th of a degree painter->restore(); }
給雷達加上模擬的掃描目標,實現起來很簡單,就是打點。
void Radar::drawPoints(QPainter *painter) { painter->save(); QColor color = QColor(200, 10, 0); QPen pen = QPen(color, 1); painter->setPen(pen); painter->setBrush(color); for(int i=0; i<this->points.count(); i++) { int r = 6; QRect rect(points[i].x() - r/2, points[i].y() - r/2, r * 2, r * 2); painter->drawEllipse(rect);// 畫實心小點 } painter->restore(); }
最終效果如下。
外層怎麼 呼叫?使用訊號和槽驅動Radar類物件。
RadarScan::RadarScan(QWidget *parent) : QMainWindow(parent) , ui(new Ui::RadarScan) { ui->setupUi(this); // start and stop connect(this, &RadarScan::radar_state_changed, ui->radar, &Radar::radar_start_control); connect(ui->startButton, &QPushButton::clicked, [=](){ emit radar_state_changed(true); }); connect(ui->stopButton, &QPushButton::clicked, [=](){ emit radar_state_changed(false); }); // speed control connect(this, &RadarScan::radar_speed_changed, ui->radar, &Radar::radar_speed_control); connect(ui->fastButton, &QPushButton::clicked, [=](){ emit radar_speed_changed(true); }); connect(ui->slowButton, &QPushButton::clicked, [=](){ emit radar_speed_changed(false); }); connect(ui->randomButton, &QPushButton::clicked, ui->radar, &Radar::radar_random_point); }
3、效果演示
尊重技術文章,轉載請註明!
Qt自定義控制元件之儀表盤2--QPaint繪製儀表盤
https://www.cnblogs.com/pingwen/p/13426304.html