Qt QGraphicsView机器人
中国好公民st 人气:0前言
最近新学了一招秘密武器,打算分享给大家!如何在QGraphicsView中制作一个跳舞的机器人。
首先,我们看一下显示效果:
让我们一起在这个炎热的夏天里奔跑吧!哈哈!
今天就让我们来解锁如何绘制这样一个会跳舞的机器人吧!
开发环境:VS2017 + Qt5.14.2
应用框架:QGraphicsView
在之前的文章中我有详细讲述QGraphicsView框架的基础,这里我们就直接讲述是如何实现的吧!
在QGraphicsView中,无论是绘制什么图形,都需要在场景中展示,并且绘图的基类是:QGraphicsItem
实现过程中遇到的知识点:
1:图形绘制。
2:如何让图形动起来。
想要让机器人动起来,首先我们要先做一个静态的机器人,今天的主要内容是如何做一个静态的机器人。
静态机器人实现
机器人的组成主要分成了三个部分:
1:机器人头(QRobotHead)
2:机器人躯干(QRobotTorso)
3:机器人肢体(QRobotLimb),用于上肢和下肢。
对应的类图:
所有的类都继承自QRobotPart,为了方便后续做动态拖动控制,要实现静态的机器人,当前QRobotPart类是不需要做任何处理的。
class QRobotPart : public QGraphicsObject { Q_OBJECT public: QRobotPart(QGraphicsItem *parent = nullptr); ~QRobotPart(); };
接下来我们就来实现机器人的三大部件吧!
1.QRobotHead
该类主要功能:机器人头类
父类:QRobotPart
首先看一下头部实现出来的效果。
头部所占的区域位置:QRectF(-10,-30,20,30);
定义到坐标轴上的区域,如下所示:
静态的机器人头部就是在图中铅笔绘制的区域。
紧接着,我们可以将眼睛、嘴巴一并绘制出来,具体实现代码如下:
void QRobotHead::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget /* = nullptr */) { /* 绘制实际的头部。 实现分为两部分: 1:如果一个图像被丢到机器人头部上,我们就画出图像。 2:否则,就画出一个带有简单矢量图形的圆形矩形机器人头部。 */ Q_UNUSED(option); Q_UNUSED(widget); painter->setBrush(m_color); //绘制:整体区域 painter->drawRoundedRect(-10, -30, 20, 30, 25, 25, Qt::RelativeSize); painter->setBrush(Qt::white); //绘制:左眼 大眼眶 painter->drawEllipse(-7, -3 - 20, 7, 7); //绘制:右眼 大眼眶 painter->drawEllipse(0, -3 - 20, 7, 7); painter->setBrush(Qt::black); //绘制:左眼 小眼珠 painter->drawEllipse(-5, -1 - 20, 2, 2); //绘制:右眼 小眼珠 painter->drawEllipse(2, -1 - 20, 2, 2); painter->setPen(QPen(Qt::black, 2)); painter->setBrush(Qt::NoBrush); //绘制:小笑脸 painter->drawArc(-6, -2 - 20, 12, 15, 190 * 16, 160 * 16); }
2.QRobotTorso
该类主要功能:机器人躯干
父类:QRobotPart
脑袋的位置确定好之后,紧接着就是躯干的位置了,就在头部坐标下面绘制就行了。
代码显示:
painter->drawRoundedRect(-20, -20, 40, 60, 25, 25, Qt::RelativeSize);
显示效果,如下图:
这样一个简易版的躯干就完成了。
为了美观起见,在对应的四肢上分别划出了四个圆圈。
void QRobotTorso::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget /* = nullptr */) { Q_UNUSED(option); Q_UNUSED(widget); painter->setBrush(m_bDragOver ? m_color.lighter(130) : m_color); painter->drawRoundedRect(-20, -20, 40, 60, 25, 25, Qt::RelativeSize); painter->drawEllipse(-25, -20, 20, 20); painter->drawEllipse(5, -20, 20, 20); painter->drawEllipse(-20, 22, 20, 20); painter->drawEllipse(0, 22, 20, 20); }
最终的显示效果,如下图:
3.QRobotLimb
该类功能:机器人肢体。包括了左右上肢以及左右下肢
父类:QRobotPart
肢体包括了:左上臂、左下臂、右上臂、右下臂、右腿上部、右腿下部、左腿上部、左腿下部。
按照一个顺时针的方式进行绘制。
对于每一个肢体,我们都采用下面的绘制图形
如此以来,只需要绘制一个圆角矩形以及一个圆形就可以了。
其实,到这里就遇到了另外一个问题:怎么确定每个肢体的位置呢?
因为是顺时针绘制,所以,在QRobotLimb中初始位置可以采用一个位置,根据创建出来的肢体不同,再对图形进行移动
假设,初始的位置区域是:QRectF(-5, -5, 40, 10)
首先,先将第一个右下臂绘制出来,显示效果如下:
看到效果图之后,会发现,右下臂应该在右肩膀的圆圈中间,那么我们只需要setPos位置就可以了。
那么,对应其他肢体的位置我们都可以这么来实现。
第一步:将所有的肢体创建出来
第二步:根据肢体的位置进行移动
实现代码,如下:
//创建:机器人躯干 QGraphicsObject *torsoItem = new QRobotTorso(this); //创建:机器人头 QGraphicsObject *headItem = new QRobotHead(this); //创建:左上臂 QGraphicsObject *upperLeftArmItem = new QRobotLimb(torsoItem); //创建:左下臂 QGraphicsObject *lowerLeftArmItem = new QRobotLimb(upperLeftArmItem); //创建:右上臂 QGraphicsObject *upperRightArmItem = new QRobotLimb(torsoItem); //创建:右下臂 QGraphicsObject *lowerRightArmItem = new QRobotLimb(upperRightArmItem); //创建:右腿上部 QGraphicsObject *upperRightLegItem = new QRobotLimb(torsoItem); //创建:右腿下部 QGraphicsObject *lowerRightLegItem = new QRobotLimb(upperRightLegItem); //创建:左腿上部 QGraphicsObject *upperLeftLegItem = new QRobotLimb(torsoItem); //创建:左腿下部 QGraphicsObject *lowerLeftLegItem = new QRobotLimb(upperLeftLegItem); headItem->setPos(0, -18); upperLeftArmItem->setPos(-15, -10); lowerLeftArmItem->setPos(30, 0); upperRightArmItem->setPos(15, -10); lowerRightArmItem->setPos(30, 0); upperRightLegItem->setPos(10, 32); lowerRightLegItem->setPos(30, 0); upperLeftLegItem->setPos(-10, 32); lowerLeftLegItem->setPos(30, 0);
显示效果,如下所示:
到这里,整体的机器人头部、躯干、四肢已经绘制完成了。
加载全部内容