Qt实现刻度盘
麻瓜编程爱好者
效果图:
项目源码
www.aliyundrive.com/s/ATH4Tz1Lh…
\
制作这个表盘最好继承自QWidget,这样可以放更方便的把它嵌入到自己的程序中
在类中声明如下成员:
protected:
void paintEvent(QPaintEvent *) override;
void timerEvent(QTimerEvent *) override;
void resizeEvent(QResizeEvent *) override;
private:
//经过计算后的刻度
float step;
//图表的中心
QPointF midpoint;
//当前数值
float nowValue;
int timer1s;
//表盘各个模块
void paintnFrame(QPainter &);
void paintPointer(QPainter &);
void paintScale(QPainter &);
void paintDisplayValue(QPainter &);
public:
//外部设置数值
float setValue;
//设置窗口大小
int windowsSize;
初始化:
setValue = nowValue = 100;
step = 2.7;
resize(windowsSize, windowsSize);
// 如果需要实时调整大小,可以将这两句放到 resizeEvent(QResizeEvent *) 中
windowsSize=400;
midpoint = QPointF(windowsSize/2, windowsSize/2);
// 可有可无的
QDial *dial = new QDial(this);
dial->move(0,0);
dial->resize(50,50);
dial->setMaximum(100);
dial->show();
connect(dial,&QDial::valueChanged,this,&pdial::dialtoNowvalue);
//这个是因为还没有想到其他实现指针跟步移动的好办法
timer1s = startTimer(10);
画出渐变底色
void pdial::paintnFrame(QPainter &painter)
{
QConicalGradient grad(0, 0, -90);
grad.setColorAt(0.1, Qt::red);
grad.setColorAt(0.5, Qt::blue);
grad.setColorAt(0.9, Qt::green);
painter.setBrush(grad);
painter.setPen(Qt::NoPen);
painter.drawPie(QRect(-midpoint.x(), -midpoint.y(), windowsSize, windowsSize),-135 * 16,-step * nowValue * 16);
painter.setBrush(Qt::white);
painter.drawEllipse(QPointF(0,0), midpoint.x() * (135 / 150.0), midpoint.y() * (135 / 150.0));
}
画出刻度
void pdial::paintScale(QPainter &painter)
{
painter.setPen(Qt::black);
for(int i = 0;i <= 10;i++){
int nowScale = i * 10;
float arc = (nowScale * step + 135) / 180 * 3.1415926;
QPointF text(midpoint.x() * (110 / 150.0) * cos(arc)-midpoint.x() / 15.0,
midpoint.y() * (110 / 150.0) * sin(arc)+midpoint.x() / 20.0);
painter.drawText(text, QString::number(nowScale));
}
painter.save();
painter.rotate(-45);
for(int i = 0;i <= 100;i++){
if(i % 10 == 0)
painter.drawLine(-midpoint.x(), 0, -1 * (midpoint.x() * (130 / 150.0)), 0);
else
painter.drawLine(-midpoint.x(), 0, -1 * (midpoint.x() * (145 / 150.0)), 0);
painter.rotate(step);
}
painter.restore();
}
画出指针
void pdial::paintPointer(QPainter &painter)
{
painter.save();
painter.rotate(-45+nowValue*step);
painter.setPen(Qt::NoPen);
QPointF triangle[] = {
QPointF(-midpoint.x(), 0),
QPointF(0, midpoint.x() * (10 / 150.0)),
QPointF(0, -midpoint.x() * (10 / 150.0))
};
painter.setBrush(Qt::red);
painter.drawPolygon(triangle,3);
float globule = -midpoint.x() * (17 / 150.0);
painter.drawEllipse(QPointF(0,0),globule,globule);
painter.setBrush(Qt::white);
painter.drawEllipse(QPointF(0,0),globule*0.4,globule*0.4);
painter.restore();
}
显示当前值
void pdial::paintDisplayValue(QPainter &painter)
{
painter.setPen(QPen(Qt::black,3));
float wid = windowsSize*(60/300.0);
QRectF rect(-wid/2,-wid/4+wid*1.2,wid,wid/2);
painter.drawRoundedRect(rect,wid/5,wid/5);
painter.drawText(rect,Qt::AlignCenter,QString::number(setValue));
}
最后在paintevent()中放出来就行了
void pdial::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::white);
painter.drawRect(0,0,width(), height());
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(midpoint);
painter.setFont(QFont("arial", windowsSize / 25));
paintnFrame(painter);
paintPointer(painter);
paintScale(painter);
paintDisplayValue(painter);
}
附录
\
指针根步移动, 非常欢迎各位提供更好的办法。
void pdial::timerEvent(QTimerEvent *ev)
{
if(ev->timerId() == timer1s){
if(nowValue < setValue){
nowValue += 1;
update();
}else if(nowValue > setValue){
nowValue -= 1;
update();
}
}
}
这是窗口大小变动事件
void pdial::resizeEvent(QResizeEvent *)
{
windowsSize = width();
midpoint = QPointF(windowsSize / 2, windowsSize / 2);
}
\
编程经验比较拉跨各位见谅>_<。
这边没有放出所有代码,可以下载源码看看 想知道如何改刻度范围的可以k我