QT中自定义控件的创建到封装到工具栏过程(一):自定义控件的创建

一、项目创建

看了网上很多自定义控件创建的文章,感觉都欠缺点东西,我借此来总结一下。
我采用的VS2017+QT5.10.1
首先我们创建一个CustomDashBoard的项目,选择Qt Designer Custom Widget程序!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里可以设置工具栏分类
程序自动生成的工程目录如下:
在这里插入图片描述

二、自定义控件的创建

一般有两种方式,可以创建带ui的也可以不带ui的,本例子使用不带ui的。
CustomDashBoard.h

#ifndef CUSTOMDASHBOARD_H
#define CUSTOMDASHBOARD_H
#define LONG1 10
#define OK1 7
#define SHORT1 5
#define SPACE1 3
#define ANGLE1 10
#include <QWidget>
#include <QtGui>
#include <QtUiPlugin/QDesignerExportWidget>
class QDESIGNER_WIDGET_EXPORT CustomDashBoard : public QWidget
{
    Q_OBJECT

public:
    CustomDashBoard(QWidget *parent = 0);
public slots:
    void setValue(qreal value);
    void setAnimating(bool enable)
    {
        m_bAnimating=enable;
        update();
    }

public:
    bool isAnimating() const
    {
        return m_bAnimating;
    }

protected:
    void paintEvent(QPaintEvent *);

    QSize sizeHint() const
    {
        return QSize(300,300);
    }

    QSize minimumSizeHint() const
    {
        return QSize(200,200);
    }

private:
    void drawOuterCircle(QPainter* painter);
    void drawInnerCircle(QPainter* painter);
    void drawMark(QPainter* painter);
    void drawCoverCircle(QPainter* painter);
    void drawColorPie(QPainter* painter);
    void drawIndicator(QPainter* painter);
    void drawCoverBall(QPainter* painter);
    void resetVariables(QPainter* painter);
    void drawTextRect(QPainter* painter);

private:
    qreal m_outerRadius;
    qreal m_innerRadius;
    qreal m_coverCircleRadius;
    qreal m_colorCircleRadius;
    qreal m_coverBallRadius;
    QPointF m_center;
    QRectF m_colorCircleRect;
    qreal m_value;
    QTimer* updateTimer;
    bool m_bReverse;
    qreal m_currentValue;
    QTimer* singleTimer;
    bool m_bAnimating;

private:
    void initVariables();

private slots:
    void UpdateGraph();
};

#endif

CustomDashBoard.cpp

#include "customdashboard.h"

CustomDashBoard::CustomDashBoard(QWidget *parent) :
    QWidget(parent)
{
     this->initVariables();
}
void CustomDashBoard::initVariables()
{
    m_outerRadius=width()>height() ? height()/2: width()/2;
    m_innerRadius=m_outerRadius/8*7;
    m_coverCircleRadius=m_outerRadius/8*4+10;
    m_colorCircleRadius=m_outerRadius/8*5;
    m_center=rect().center();
    m_value=0;
    m_currentValue=0;
    updateTimer=new QTimer(this);
    updateTimer->setInterval(10);
    connect(updateTimer,SIGNAL(timeout()),this,SLOT(UpdateGraph()));
    singleTimer=new QTimer(this);
    singleTimer->setInterval(100);
    connect(singleTimer,SIGNAL(timeout()),this,SLOT(update()));
    singleTimer->start();
}

void CustomDashBoard::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing);
    resetVariables(&painter);
    drawOuterCircle(&painter);
    drawInnerCircle(&painter);
    drawColorPie(&painter);
    drawCoverCircle(&painter);
    drawMark(&painter);
    drawIndicator(&painter);
    drawCoverBall(&painter);
    drawTextRect(&painter);
    painter.end();
}

void CustomDashBoard::drawOuterCircle(QPainter *painter)
{
    painter->save();

    QRadialGradient outerGradient(m_center,m_outerRadius,m_center);
    outerGradient.setColorAt(0.0,QColor(200,200,200));
    outerGradient.setColorAt(0.9,QColor(80,80,80));
    outerGradient.setColorAt(0.95,QColor(180,180,180));
    outerGradient.setColorAt(1.0,QColor(80,80,80));

    painter->setPen(Qt::NoPen);
    painter->setBrush(outerGradient);
    painter->drawEllipse(m_center,m_outerRadius,m_outerRadius);
    painter->restore();
}

void CustomDashBoard::drawInnerCircle(QPainter *painter)
{
    painter->save();
    QRadialGradient innerGradient(m_center,m_innerRadius,m_center);
    innerGradient.setColorAt(0.0,QColor(130,130,130));
    innerGradient.setColorAt(0.7,QColor(130,130,130));
    innerGradient.setColorAt(1.0,QColor(80,80,80));
    painter->setPen(Qt::NoPen);
    painter->setBrush(innerGradient);
    painter->drawEllipse(m_center,m_innerRadius,m_innerRadius);

    painter->restore();
}

void CustomDashBoard::drawMark(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::white);
    painter->translate(m_center);

    qreal dAngle=(qreal)270/100;
    qreal startAngle=45;
    int value=0;
    QString strValue;
    for(int i=0;i<=100;i++)
    {
        painter->save();
        painter->rotate(startAngle);

        if(i%10==0)
        {
            strValue=tr("%1").arg(value);
            qreal textWidth=fontMetrics().width(strValue);
            qreal textHeight=fontMetrics().height();
            QPointF bottomPot(0,m_colorCircleRadius+SPACE1);
            QPointF topPot(0,m_colorCircleRadius+SPACE1+LONG1);
            painter->drawLine(bottomPot,topPot);
            value+=10;

            painter->save();
            QPointF textPot(0-textWidth/2,m_colorCircleRadius+SPACE1+LONG1+SPACE1+textHeight);
            painter->translate(textPot);
            painter->rotate(180);
            painter->drawText(QPointF(-textWidth,textHeight/2),strValue);
            painter->restore();
        }
        else if(i%5==0)
        {
            QPointF bottomPot(0,m_colorCircleRadius+SPACE1);
            QPointF topPot(0,m_colorCircleRadius+SPACE1+OK1);
            painter->drawLine(bottomPot,topPot);

        }
        else
        {
            QPointF bottomPot(0,m_colorCircleRadius+SPACE1);
            QPointF topPot(0,m_colorCircleRadius+SPACE1+SHORT1);
            painter->drawLine(bottomPot,topPot);
        }
        painter->restore();
        startAngle+=dAngle;
    }
    painter->restore();
}

void CustomDashBoard::drawCoverBall(QPainter *painter)
{
    painter->save();

    qreal ballRadius=m_outerRadius/7;
    m_coverBallRadius=ballRadius;
    QRadialGradient ballGradient(m_center,ballRadius,m_center);
    ballGradient.setColorAt(0.0,QColor(140,140,140));
    ballGradient.setColorAt(0.7,QColor(140,140,140));
    ballGradient.setColorAt(1.0,QColor(60,60,60));
    painter->setBrush(ballGradient);
    painter->setPen(Qt::NoPen);
    painter->drawEllipse(m_center,ballRadius,ballRadius);

    painter->restore();
}

void CustomDashBoard::drawTextRect(QPainter *painter)
{
    painter->save();
    qreal rectWidth=m_coverCircleRadius/5;

    QPointF topLeftPot(m_center.x()-1.5*rectWidth,m_center.y()+rectWidth*2);
    QPointF bottomRightPot(topLeftPot.x()+3*rectWidth,topLeftPot.y()+rectWidth*2);
    QRectF textRect(topLeftPot,bottomRightPot);

    painter->setPen(Qt::NoPen);
    painter->setBrush(QColor(0,170,255));
    painter->setOpacity(0.6);
    painter->drawRoundRect(textRect,ANGLE1,ANGLE1);

    qreal fontSize=textRect.height()/2;
    QFont font;
    font.setPointSize(fontSize);
    painter->setFont(font);

    painter->setOpacity(1.0);
    painter->setPen(Qt::black);
    QString strValue;
    strValue=tr("%1").arg(m_value);
    painter->drawText(textRect,Qt::AlignHCenter|Qt::AlignVCenter,strValue);
    painter->restore();
}

void CustomDashBoard::drawCoverCircle(QPainter *painter)
{
    painter->save();
    painter->setBrush(QColor(130,130,130));
    painter->setPen(Qt::NoPen);
    painter->drawEllipse(m_center,m_coverCircleRadius,m_coverCircleRadius);
    painter->restore();
}

void CustomDashBoard::drawColorPie(QPainter *painter)
{
    painter->save();

    QPointF topLeftPot(m_center.x()-m_colorCircleRadius,m_center.y()-m_colorCircleRadius);
    QPointF bottomRightPot(m_center.x()+m_colorCircleRadius,m_center.y()+m_colorCircleRadius);
    m_colorCircleRect=QRectF(topLeftPot,bottomRightPot);
    painter->setPen(Qt::NoPen);

    QConicalGradient greenGradient(m_center,m_innerRadius);
    greenGradient.setColorAt(0.0,QColor(0,30,0));
    greenGradient.setColorAt(0.25,QColor(0,230,0));
    greenGradient.setColorAt(1.0,QColor(0,230,0));
    painter->setBrush(Qt::green);
    painter->drawPie(m_colorCircleRect,45*16,180*16);

    painter->setBrush(QColor(218,218,0));
    painter->drawPie(m_colorCircleRect,0*16,45*16);

    painter->setBrush(QColor(240,50,50));
    painter->drawPie(m_colorCircleRect,0,-45*16);

    painter->restore();
}

void CustomDashBoard::drawIndicator(QPainter *painter)
{
    painter->save();

    painter->translate(m_center);
    qreal increment=(qreal)270/100;
    qreal changedAngle=45+increment*m_currentValue;
    painter->rotate(changedAngle);

    QPointF topPot(0,m_colorCircleRadius+LONG1);
    QPointF bottomLeftPot(-m_coverBallRadius/3,0);
    QPointF bottomRightPot(m_coverBallRadius/3,0);
    painter->setPen(Qt::NoPen);

    QLinearGradient indicatorGradient(topPot,bottomLeftPot);
    indicatorGradient.setColorAt(0.0,QColor(236,187,62));
    indicatorGradient.setColorAt(0.5,QColor(220,147,0));
    indicatorGradient.setColorAt(1.0,QColor(236,187,62));

    painter->setBrush(indicatorGradient);
    QVector<QPointF> potVec;
    potVec.push_back(topPot);
    potVec.push_back(bottomLeftPot);
    potVec.push_back(bottomRightPot);

    painter->drawPolygon(potVec);
    painter->restore();
}

void CustomDashBoard::resetVariables(QPainter *painter)
{
    m_outerRadius=width()>height() ? height()/2: width()/2;
    m_innerRadius=m_outerRadius/8*7;
    m_coverCircleRadius=m_outerRadius/8*4+10;
    m_colorCircleRadius=m_outerRadius/8*5;

    m_center=rect().center();
}

void CustomDashBoard::setValue(qreal value)
{
    if(value>m_value)
    {
        m_bReverse=false;
        m_value=value;

        if(!m_bAnimating)
        {
            m_currentValue=m_value;
        }
    }
    else if(value<m_value)
    {
        m_bReverse=true;
        m_value=value;
        if(!m_bAnimating)
        {
            m_currentValue=m_value;
        }
    }
    else
    {
        return ;
    }
    updateTimer->start();
}

void CustomDashBoard::UpdateGraph()
{
    if(!m_bReverse)
    {
        m_currentValue+=0.5;

        if(m_currentValue>=m_value)
        {
            updateTimer->stop();
        }
    }
    else
    {
        m_currentValue-=0.5;
        if(m_currentValue<=m_value)
        {
            updateTimer->stop();
        }
    }
    update();
}

曾尝试使用vs进行此步骤,生成没有问题,但是在后期引用会出现小问题,网上解决方案较为复杂,需要重新编译元lib文件,所以建议大家使用Qt Creater创建。主要问题时QDESIGNER_WIDGET_EXPORT 在vs会被禁止。

三、编译dll

	选择release版本,因为qt 设计工具栏只识别release版本,选择好后,点一下那个锤子即可

在这里插入图片描述

四、效果

这是生成的文件目录,我们主要使用dll、lib和头文件,因为这个是类库类型,我们必须调用才能看到,除非自己加ui项目展示。至此,自定义控件创建完成。
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值