问题描述(仪器仪表中旋转型滑块):
如以下视频所示,仪器仪表中经常使用可以一个旋转滑动的三角形游标作为控制部件。QGraphicsItem在缺省情况下,运动是随意的,因此限制需要限制其运动为绕定点旋转的圆周运动。
Qt实现的仪器仪表类控件演示
QGraphicsItem实现旋转型滑块
从TriangleItem类中派生出TriangleRotateItem类,实现只可绕某一定点旋转的Item。TriangleItem类在我的另一篇文章《QGraphicsItem实现仪器仪表盘中直动型滑块》中已经介绍。
要实现上述视频中三角滑块绕某一定点运动,并且滑块总是指向旋转中心,就需要滑块在绕旋转中心作圆周运动的同时,绕自身中心旋转。滑块绕旋转中心作圆周运动,就像地球的公转;绕自身中心旋转,就像地球本身的自转。
具体的实现代码在:QVariant TriangleRotateItem::itemChange(GraphicsItemChange change, const QVariant &value)中,下边上代码。
TriangleRotateItem类.h文件
#ifndef TRIANGLEROTATEITEM_H
#define TRIANGLEROTATEITEM_H
#include <QObject>
#include"triangleitem.h"
class TriangleRotateItem : public TriangleItem
{
Q_OBJECT
public:
explicit TriangleRotateItem(QGraphicsItem* parentItem=NULL,QObject *parent = nullptr);
void setRotateRadius(double radius); //设置旋转半径
void setDegree(double degree);//设置角度值
void setRotateCenter(const QPointF ¢erPos);//设置旋转中心
protected:
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);
signals:
void sig_degree(double); //旋转时,发出角度信号
private:
QPointF centerPointF;
double m_radius=50;
};
#endif // TRIANGLEROTATEITEM_H
TriangleRotateItem类.cpp文件
#include "trianglerotateitem.h"
#include<QGraphicsScene>
#include<QGraphicsView>
TriangleRotateItem::TriangleRotateItem(QGraphicsItem *parentItem, QObject *parent)
:TriangleItem(parentItem,parent)
{
centerPointF=QPointF(0,0);
setBrush(Qt::red);
}
void TriangleRotateItem::setRotateRadius(double radius)
{
m_radius=radius;
update();
}
void TriangleRotateItem::setRotateCenter(const QPointF ¢erPos)
{
centerPointF=centerPos;
update();
}
void TriangleRotateItem::setDegree(double degree)
{
QLineF lineF(centerPointF,centerPointF+QPointF(m_radius,0));
lineF.setAngle(-degree+90);
setPos(lineF.p2());
update();
}
QVariant TriangleRotateItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
if(change==ItemPositionChange)
{
QLineF lineF(centerPointF,value.toPointF());
lineF.setLength(m_radius);
double degree=lineF.angle(); //QLineF的angle()逆时针为正
setRotation(-degree);//Qt中旋转以顺时针为正 绕局部坐标系原点自转
degree=90-degree; //转化为0-360之间,正北方向为0,顺时针为正
if(degree<0)
{
degree+=360;
}
emit sig_degree(degree);//发送角度
emit sig_posChanged(lineF.p2());
return lineF.p2(); //绕旋转中心的公转
}
return QGraphicsPolygonItem::itemChange(change,value);
}
测试程序可看直动滑块和旋转滑块的实现