Qt并没有相关api直接绘制弧形文字,但提供了曲线绘制相关类,所以只能另辟蹊径,使用QPainterPath先生成曲线,然后通过曲线上的点来定位每个文字并draw出来。
QML具体做法为从QQuickPaintedItem继承,在派生类中实现paint函数
代码如下:
void ViewItem::paint(QPainter *painter)
{
painter->setRenderHint(QPainter::Antialiasing);
QRectF rect(200, 200, 400, 300);
painter->drawRect(rect);
auto arcRect = rect;
arcRect.setHeight(rect.height() * 2); //绘制椭圆上半圆,所以椭圆矩形高度*2
QPainterPath path;
path.arcMoveTo(arcRect, 170); //起始度数
path.arcTo(arcRect, 170, -160); //起始度数,曲线弧度
painter->drawPath(path);
QFont font("", 20);
painter->setFont(font);
QFontMetrics fm(font);
auto textH = fm.height();
QString text = "测试QML弧形文字绘制";
for(auto i=0; i< text.length(); i++)
{
const auto& word = text.at(i);
painter->save();
auto per = i / (float)(text.length() - 1);
auto pt = path.pointAtPercent(per);
painter->translate(pt.x(), pt.y());
auto ang = path.angleAtPercent(per);
painter->rotate(-ang);
auto textW = fm.horizontalAdvance(word);
painter->drawText(-textW/2, 0, textW, textH, Qt::AlignCenter, word);
painter->restore();
}
}
曲线与文本效果如下:
关于度数说明,如下图
上半圆从右往左,逆时针0°到180°,所以为了使线条从从往右绘制,所以起始度数设置为170°(具体看个人需求),曲线弧度负数为反向,左边-10,右边-10,故为-160°(具体看个人需求)
QPainterPath path;
path.arcMoveTo(arcRect, 170); //起始度数
path.arcTo(arcRect, 170, -160); //起始度数,曲线弧度
使用QPainterPath的两个函数pointAtPercent和angleAtPercent,能获取到每个文本对于的位置和旋转角度。
drawText注意文字偏移即可。
凹形曲线,使用椭圆下半圆使用相同方法绘制即可。