当前位置:网站首页>QT中自定义控件的创建到封装到工具栏过程(一):自定义控件的创建
QT中自定义控件的创建到封装到工具栏过程(一):自定义控件的创建
2022-07-07 15:32:00 【God港】
一、项目创建
看了网上很多自定义控件创建的文章,感觉都欠缺点东西,我借此来总结一下。
我采用的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项目展示。至此,自定义控件创建完成。
边栏推荐
- 【C 语言】 题集 of Ⅹ
- The latest interview experience of Android manufacturers in 2022, Android view+handler+binder
- 最新高频Android面试题目分享,带你一起探究Android事件分发机制
- 值得一看,面试考点与面试技巧
- How can laravel get the public path
- LeetCode 1696. 跳跃游戏 VI 每日一题
- 【MySql进阶】索引详解(一):索引数据页结构
- 1亿单身男女“在线相亲”,撑起130亿IPO
- Find tags in prefab in unity editing mode
- 【DesignMode】享元模式(Flyweight Pattern)
猜你喜欢
随机推荐
预测——灰色预测
OpenGL personal notes
LeetCode 152. 乘积最大子数组 每日一题
Pycharm terminal enables virtual environment
LeetCode 1031. 两个非重叠子数组的最大和 每日一题
数据中台落地实施之法
Three. JS series (3): porting shaders in shadertoy
Introduction to ThinkPHP URL routing
Have fun | latest progress of "spacecraft program" activities
PHP realizes wechat applet face recognition and face brushing login function
The differences between exit, exit (0), exit (1), exit ('0 '), exit ('1'), die and return in PHP
低代码(lowcode)帮助运输公司增强供应链管理的4种方式
预售17.9万,恒驰5能不能火?产品力在线,就看怎么卖
C语言进阶——函数指针
编程模式-表驱动编程
第九届 蓝桥杯 决赛 交换次数
华东师大团队提出,具有DNA调控电路的卷积神经网络的系统分子实现
偶然升职的内心独白
three. JS create cool snow effect
01tire+ chain forward star +dfs+ greedy exercise one






