Qt自定義控件實現(xiàn)儀表盤
更新時間:2022年02月08日 14:06:38 作者:EEer!
這篇文章主要為大家詳細介紹了Qt如何自定義控件實現(xiàn)儀表盤,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
1.預覽圖

2. 代碼
頭文件
#ifndef MOTORMETER_H
#define MOTORMETER_H
#include <QWidget>
#include <QDebug>
#include <QtMath>
#include <QDialog>
#include <QPainter>
#include <QPaintEvent>
#include <QPainterPath>
#include <QRadialGradient>
class motormeter : public QWidget
{
Q_OBJECT
public:
explicit motormeter(QWidget *parent = nullptr);
~motormeter();
protected:
void paintEvent(QPaintEvent*);
private:
int degRotate =-120;
private:
void DrawPoint(QPainter&,int);
void DrawDigital(QPainter&,int);
void DrawCircle(QPainter&,int);
void DrawSmallScale(QPainter&,int);
void DrawBigScale(QPainter&,int);
void DrawText(QPainter&,int);
void DrawPointer(QPainter&,int);
void drawIndicator(QPainter *painter);
public slots:
void valueChanged(int);
};
#endif // MOTORMETER_H
源文件
#include "motormeter.h"
motormeter::motormeter(QWidget *parent) : QWidget(parent)
{
}
motormeter::~motormeter()
{
}
void motormeter::paintEvent(QPaintEvent*)
{
QPainter painter(this);
int width=this->width();
int height=this->height();
int radius=((width>height)?height:width)/2;
//移動畫筆到中下方
painter.translate(width/2,height*0.6);
//啟用反鋸齒
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(Qt::NoPen);
//設置畫刷顏色
painter.setBrush(QColor(138,43,226));
DrawPoint(painter,radius);
DrawDigital(painter,radius-10);
DrawCircle(painter,radius-35);
DrawSmallScale(painter,radius-60);
DrawBigScale(painter,radius-75);
DrawText(painter,radius/2);
DrawPointer(painter,radius-100);
}
//繪制外圈點
void motormeter::DrawPoint(QPainter& painter,int radius)
{
//組裝點的路徑圖
QPainterPath pointPath;
pointPath.moveTo(-2,-2);
pointPath.lineTo(2,-2);
pointPath.lineTo(2,2);
pointPath.lineTo(0,4);
pointPath.lineTo(-2,2);
//繪制13個小點
for(int i=0;i<13;++i){
QPointF point(0,0);
painter.save();
painter.setBrush(QColor(255,127,80));
//計算并移動繪圖對象中心點
point.setX(radius*qCos(((210-i*20)*M_PI)/180));
point.setY(radius*qSin(((210-i*20)*M_PI)/180));
//計算并移動繪圖對象的中心點
painter.translate(point.x(),-point.y());
//計算并選擇繪圖對象坐標
painter.rotate(-120+i*20);
//繪制路徑
painter.drawPath(pointPath);
painter.restore();
}
}
//繪制外圈數(shù)字,原理和繪制圓圈點一樣
void motormeter::DrawDigital(QPainter& painter,int radius)
{
//設置畫筆,畫筆默認NOPEN
painter.setPen(QColor(218,112,214));
QFont font;
font.setFamily("Cambria");
font.setPointSize(15);
painter.setFont(font);
for(int i=0;i<13;++i){
QPointF point(0,0);
painter.save();
point.setX(radius*qCos(((210-i*20)*M_PI)/180));
point.setY(radius*qSin(((210-i*20)*M_PI)/180));
painter.translate(point.x(),-point.y());
painter.rotate(-120+i*20);
painter.drawText(-15, -5, 40, 30,Qt::AlignCenter,QString::number(i*20));
painter.restore();
}
//還原畫筆
painter.setPen(Qt::NoPen);
}
//繪制外圈
void motormeter::DrawCircle(QPainter& painter,int radius)
{
//保存繪圖對象
painter.save();
//計算大小圓路徑
QPainterPath outRing;
QPainterPath inRing;
outRing.moveTo(0,0);
inRing.moveTo(0,0);
outRing.arcTo(-radius,-radius, 2*radius,2*radius,-31,242);
inRing.addEllipse(-radius+20,-radius+20,2*(radius-20),2*(radius-20));
outRing.closeSubpath();
//設置漸變色k
QRadialGradient radialGradient(0,0,radius,0,0);
radialGradient.setColorAt(0.93,QColor(138,43,226));
radialGradient.setColorAt(1,QColor(0,0,0));
//設置畫刷
painter.setBrush(radialGradient);
//大圓減小圓
painter.drawPath(outRing.subtracted(inRing));
//painter.drawPath(outRing);
//painter.drawPath(inRing);
painter.restore();
}
//繪制刻度
void motormeter::DrawSmallScale(QPainter& painter,int radius)
{
//組裝點的路徑圖
QPainterPath pointPath;
pointPath.moveTo(-2,-2);
pointPath.lineTo(-1,-4);
pointPath.lineTo(1,-4);
pointPath.lineTo(2,-2);
pointPath.lineTo(1,8);
pointPath.lineTo(-1,8);
//繪制121個小點
for(int i=0;i<121;++i){
QPointF point(0,0);
painter.save();
point.setX(radius*qCos(((210-i*2)*M_PI)/180));
point.setY(radius*qSin(((210-i*2)*M_PI)/180));
painter.translate(point.x(),-point.y());
painter.rotate(-120+i*2);
if(i>=90) painter.setBrush(QColor(250,0,0));
painter.drawPath(pointPath);
painter.restore();
}
}
//繪制刻度
void motormeter::DrawBigScale(QPainter& painter,int radius)
{
//組裝點的路徑圖
QPainterPath pointPath1;
pointPath1.moveTo(-2,-2);
pointPath1.lineTo(-1,-4);
pointPath1.lineTo(1,-4);
pointPath1.lineTo(2,-2);
pointPath1.lineTo(1,8);
pointPath1.lineTo(-1,8);
QPainterPath pointPath2;
pointPath2.moveTo(-2,-2);
pointPath2.lineTo(-1,-4);
pointPath2.lineTo(1,-4);
pointPath2.lineTo(2,-2);
pointPath2.lineTo(1,15);
pointPath2.lineTo(-1,15);
//繪制25個刻度
for(int i=0;i<25;++i){
QPointF point(0,0);
painter.save();
point.setX(radius*qCos(((210-i*10)*M_PI)/180));
point.setY(radius*qSin(((210-i*10)*M_PI)/180));
painter.translate(point.x(),-point.y());
painter.rotate(-120+i*10);
if(i>=18) painter.setBrush(QColor(250,0,0));
if(i%2){
painter.drawPath(pointPath1);
}
else{
painter.drawPath(pointPath2);
}
painter.restore();
}
}
//繪制中心文字km/h
void motormeter::DrawText(QPainter& painter,int radius)
{
painter.save();
painter.setPen(QColor(153,51,250));
QFont font;
font.setFamily("Cambria");
font.setPointSize(16);
painter.setFont(font);
painter.drawText(-25, -radius, 60, 30,Qt::AlignCenter,QString("km/h"));
painter.restore();
}
//繪制指針
void motormeter::DrawPointer(QPainter& painter,int radius)
{
//組裝點的路徑圖
QPainterPath pointPath;
pointPath.moveTo(10,0);
pointPath.lineTo(1,-radius);
pointPath.lineTo(-1,-radius);
pointPath.lineTo(-10,0);
pointPath.arcTo(-10,0,20,20,180,180);
QPainterPath inRing;
inRing.addEllipse(-5,-5,10,10);
painter.save();
QRadialGradient radialGradient(0,0,radius,0,0);
radialGradient.setColorAt(0,QColor(0,199,140,150));
radialGradient.setColorAt(1,QColor(255,153,18,150));
//計算并選擇繪圖對象坐標
painter.rotate(degRotate);
painter.setBrush(radialGradient);
painter.drawPath(pointPath.subtracted(inRing));
painter.restore();
}
void motormeter::valueChanged(int value)
{
this->degRotate = value;
update();
}3. 用法
創(chuàng)建類,然后在創(chuàng)建的頭文件和源文件里面添加上述代碼


在UI界面里面拖拽widget部件

將widget部件提升為自定義的類,在提升的類名稱里面填入上面源代碼里面的類名

調(diào)用函數(shù)如下,在設計師界面類里面調(diào)用這個函數(shù)即可
void motormeter::valueChanged(int value)
{
this->degRotate = value;
update();
}
//設置背景墻 QPalette bgpal= palette(); bgpal.setColor(QPalette::Background,QColor(0,0,0)); setPalette (bgpal); ui->motormeter->valueChanged(a);
以上就是Qt自定義控件實現(xiàn)儀表盤的詳細內(nèi)容,更多關于Qt儀表盤的資料請關注腳本之家其它相關文章!
相關文章
C++調(diào)用python(執(zhí)行py文件)的全過程
這篇文章主要給大家介紹了關于C++調(diào)用python(執(zhí)行py文件)的相關資料,文中通過圖文以及實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2021-12-12

