QPainter - 八卦时钟
上一篇我们在画时钟的时候,已经把基本的钟表指针和刻度都绘制过了
想要完成八卦时钟,就要绘制这个里面的八卦了。
先上个图:
有人和我说八卦不能转
再来一张图:
背景的绘制
我们需要删除之前所绘制的白色背景, 并且将背景修改为黄色
我这里是直接使用的styleSheet设置的背景色
setStyleSheet("background-color:yellow;");
太极八卦的绘制
这里面是三部分:
- 太极的绘制
太极的绘制我们添加绘制太极的函数.
太极的阴阳鱼就是一个半圆添加一个圆和裁减一个圆,我们使用QPainterPath很容易实现这个。
之后我们在给添加的圆的中心再绘制一个颜色相反的小圆作为鱼眼,这样即可完成阴阳鱼的绘制
void Universe::drawUniverse(QPainter &painter) { int radius = radius_ * 0.2; painter.save(); painter.rotate(-degree_); // 绘制阳鱼 painter.setPen(Qt::NoPen); QPainterPath circle, tmp; // 这个后面的两个参数时开始度数和移动过的度数 circle.arcTo(-radius, -radius, radius * 2, radius * 2, 270, 180); tmp.addEllipse(QPointF(0, -radius / 2), radius / 2, radius / 2); circle -= tmp; tmp.clear(); tmp.addEllipse(QPointF(0, radius / 2), radius / 2, radius / 2); circle += tmp; painter.fillPath(circle, Qt::white); tmp.clear(); tmp.addEllipse(QPointF(0, radius / 2), radius / 4, radius / 4); painter.fillPath(tmp, Qt::black); // 绘制阴鱼,与阳鱼是一样的 circle.clear(); circle.arcTo(-radius, -radius, radius * 2, radius * 2, 90, 180); tmp.clear(); tmp.addEllipse(QPointF(0, -radius / 2), radius / 2, radius / 2); circle += tmp; tmp.clear(); tmp.addEllipse(QPointF(0, radius / 2), radius / 2, radius / 2); circle -= tmp; painter.fillPath(circle, Qt::black); tmp.clear(); tmp.addEllipse(QPointF(0, -radius / 2), radius / 4, radius / 4); painter.fillPath(tmp, Qt::white); painter.restore(); }
- 八卦的绘制
八卦的绘制是比阴阳鱼更简单的,八卦对应的是八个方位,我们按照方位给加上对应的卦象即可,我这里给了卦象顺序和描述
void Universe::drawBagua(QPainter &painter) { // 因为每个卦象不一样,因此需要单独去绘制,这里写了8个 int bottom = - radius_ * 0.25; int lineLength = 12; int midLength = 2; int interval = 4; painter.setPen(QPen(Qt::red, 2)); painter.save(); // painter.rotate(degree_); /* 乾三连 */ QPoint point(-lineLength / 2, bottom); QPoint point2(lineLength / 2, bottom); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval); point2 = QPoint(lineLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval * 2); point2 = QPoint(lineLength / 2, bottom - interval * 2); painter.drawLine(point, point2); /* 巽下断 */ painter.rotate(45); point = QPoint(-lineLength / 2, bottom); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom ); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom); point2 = QPoint(lineLength / 2, bottom ); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval); point2 = QPoint(lineLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval * 2); point2 = QPoint(lineLength / 2, bottom - interval * 2); painter.drawLine(point, point2); /* 坎中满 */ painter.rotate(45); point = QPoint(-lineLength / 2, bottom); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom ); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom); point2 = QPoint(lineLength / 2, bottom ); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval); point2 = QPoint(lineLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval * 2); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom - interval * 2); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom - interval * 2); point2 = QPoint(lineLength / 2, bottom - interval * 2); painter.drawLine(point, point2); /* 艮覆碗 */ painter.rotate(45); point = QPoint(-lineLength / 2, bottom); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom ); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom); point2 = QPoint(lineLength / 2, bottom ); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom - interval); point2 = QPoint(lineLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval *2); point2 = QPoint(lineLength / 2, bottom - interval * 2); painter.drawLine(point, point2); /* 坤六断 */ painter.rotate(45); point = QPoint(-lineLength / 2, bottom); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom ); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom); point2 = QPoint(lineLength / 2, bottom ); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom - interval); point2 = QPoint(lineLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval * 2); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom - interval * 2); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom - interval * 2); point2 = QPoint(lineLength / 2, bottom - interval * 2); painter.drawLine(point, point2); /* 震仰盂 */ painter.rotate(45); point = QPoint(-lineLength / 2, bottom); point2 = QPoint(lineLength / 2, bottom); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom - interval); point2 = QPoint(lineLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval * 2); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom - interval * 2); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom - interval * 2); point2 = QPoint(lineLength / 2, bottom - interval * 2); painter.drawLine(point, point2); /* 离中虚 */ painter.rotate(45); point = QPoint(-lineLength / 2, bottom); point2 = QPoint(lineLength / 2, bottom); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom - interval); point2 = QPoint(lineLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval * 2); point2 = QPoint(lineLength / 2, bottom - interval * 2); painter.drawLine(point, point2); /* 兑上缼 */ painter.rotate(45); point = QPoint(-lineLength / 2, bottom); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom); point2 = QPoint(lineLength / 2, bottom); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval); point2 = QPoint(-lineLength / 4 + midLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(lineLength / 4 - midLength/2, bottom - interval); point2 = QPoint(lineLength / 2, bottom - interval); painter.drawLine(point, point2); point = QPoint(-lineLength / 2, bottom - interval * 2); point2 = QPoint(lineLength / 2, bottom - interval * 2); painter.drawLine(point, point2); painter.restore(); }
- 外部文字的绘制
八卦外部的文字绘制不复杂,但是八角形坐标得算一下, 这里也是贴出代码,初中的三角函数知识,不做解释,如果不明白可以自己画画图
int radiusIn = 100 * 0.85; int radiusOut = 100 * 1.15; int radiusText = 100 * 0.5; const QStringList list{"乾", "巽", "坎", "艮", "坤", "震", "离", "兑"}; double pointInX = qSin(M_PI /180.0 * 22.5) * radiusIn / 2; double pointOutX = qSin(M_PI /180.0 * 22.5) * radiusOut / 2; double pointInY = radiusIn / 2 * qCos(M_PI /180.0 * 22.5); double pointOutY = radiusOut / 2 * qCos(M_PI /180.0 * 22.5);
void Universe::drawBaguaText(QPainter &painter) { painter.save(); // painter.rotate(degree_); painter.setPen(QPen(Qt::black, 1)); for(int i = 0; i < 8; i++) { painter.drawLine(-pointInX, pointInY, pointInX, pointInY); painter.drawLine(-pointOutX, pointOutY, pointOutX, pointOutY); painter.drawLine(pointInX, pointInY, pointOutX, pointOutY); painter.drawText(QRectF(-5, -radiusText, 10, 10), Qt::AlignCenter, list[i]); painter.rotate(45); } painter.restore(); update(); }
至此我们完成了所有的绘制部分,之前绘制钟表的背景部分的代码可以删除,我们只留下刻度和指针的代码,对了给指针的中心加一个白色的点来模拟固定的小钉子,不然看着有点小难受。