Qt、QTransform旋转
Qt, QTransform rotation
我正在尝试绘制文本 "on cylinder"。这意味着,我有五行文本。顶行沿 X 轴旋转 10 度。第二个为5度。中间根本没有旋转。四人行旋转-5度。五是旋转-10度。
第 1、2、3 行绘制正常,但 4,5 行出现问题。我究竟做错了什么 ?
我提供了一个图像来理解问题和代码片段:
for( int i = 0; i < iterationsCount; ++i )
{
const QRect r( x2, y2, textWidth, itemHeight );
const QString text = sections.at( section ).values.at( index );
int rsc = 0;
p->save();
rsc = widgetHeight / 2 - y;
p->setTransform(QTransform().rotate(rsc, Qt::XAxis));
if( type == Section::DaySectionShort ||
type == Section::DaySectionLong )
{
QStringList values = text.split( QLatin1Char( ' ' ) );
p->setPen(
lighterColor( opt.palette.color( QPalette::WindowText ), 75 ) );
p->drawText( r, Qt::AlignLeft | Qt::TextSingleLine, values.at( 0 ) );
p->setPen( opt.palette.color( QPalette::WindowText ) );
p->drawText( r, Qt::AlignLeft | Qt::TextSingleLine, values.at( 1 ) );
}
else
{
p->drawText( r, Qt::AlignLeft | Qt::TextSingleLine, text );
}
p->setTransform(QTransform().rotate(-rsc, Qt::XAxis));
index = nextIndex( index, sections.at( section ).values.size() );
y += itemHeight + itemTopMargin;
p->restore();
}
由于您没有提供重现问题的最小完整 代码,我猜不出那里出了什么问题。但最可能的原因是 rsc
计算不正确。至少以下草稿作品:
#include <QtCore>
#include <QtGui>
#include <QtWidgets>
class MyWidget: public QWidget
{
public:
MyWidget(QWidget *parent = nullptr)
: QWidget(parent)
{
QFont f = font();
f.setPointSize(15);
setFont(f);
}
protected:
void paintEvent(QPaintEvent *event) override
{
QWidget::paintEvent(event);
QPainter p(this);
const int itemHeight = fontMetrics().height();
const int itemTopMargin = 15;
const int xOffset = 15;
int y = itemHeight;
for (size_t i = 0; i < 5; ++i) {
// The angle is in range [-40, 40]. Remove " * 4" for [-10, 10].
const int rsc = (10 - 5 * i) * 4;
qDebug() << i << ":\t" << rsc << "\t" << y;
/*
Rotation must be performed relative to central point of the
drawn item. Transformations below are applied in reverse order.
At first translate item to make it's center in (0, 0). At
second rotate it relative to X axis. At third move the item to
desired position.
*/
QTransform transform;
transform.translate(xOffset, y + itemHeight / 2);
transform.rotate(rsc, Qt::XAxis);
transform.translate(0, - itemHeight / 2);
p.setTransform(transform);
p.drawText(QPoint(), QString("(Item no. %1)").arg(i + 1));
y += itemHeight + itemTopMargin;
}
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MyWidget widget;
widget.setMaximumSize(200, 250);
widget.show();
return app.exec();
}
这里使用的转换很复杂,因为需要相对于它的中心旋转每个项目 y
,而不是 y = 0
。也可能是这样。
增加了字体和角度以更好地查看考虑的效果。
我正在尝试绘制文本 "on cylinder"。这意味着,我有五行文本。顶行沿 X 轴旋转 10 度。第二个为5度。中间根本没有旋转。四人行旋转-5度。五是旋转-10度。 第 1、2、3 行绘制正常,但 4,5 行出现问题。我究竟做错了什么 ? 我提供了一个图像来理解问题和代码片段:
for( int i = 0; i < iterationsCount; ++i )
{
const QRect r( x2, y2, textWidth, itemHeight );
const QString text = sections.at( section ).values.at( index );
int rsc = 0;
p->save();
rsc = widgetHeight / 2 - y;
p->setTransform(QTransform().rotate(rsc, Qt::XAxis));
if( type == Section::DaySectionShort ||
type == Section::DaySectionLong )
{
QStringList values = text.split( QLatin1Char( ' ' ) );
p->setPen(
lighterColor( opt.palette.color( QPalette::WindowText ), 75 ) );
p->drawText( r, Qt::AlignLeft | Qt::TextSingleLine, values.at( 0 ) );
p->setPen( opt.palette.color( QPalette::WindowText ) );
p->drawText( r, Qt::AlignLeft | Qt::TextSingleLine, values.at( 1 ) );
}
else
{
p->drawText( r, Qt::AlignLeft | Qt::TextSingleLine, text );
}
p->setTransform(QTransform().rotate(-rsc, Qt::XAxis));
index = nextIndex( index, sections.at( section ).values.size() );
y += itemHeight + itemTopMargin;
p->restore();
}
由于您没有提供重现问题的最小完整 代码,我猜不出那里出了什么问题。但最可能的原因是 rsc
计算不正确。至少以下草稿作品:
#include <QtCore>
#include <QtGui>
#include <QtWidgets>
class MyWidget: public QWidget
{
public:
MyWidget(QWidget *parent = nullptr)
: QWidget(parent)
{
QFont f = font();
f.setPointSize(15);
setFont(f);
}
protected:
void paintEvent(QPaintEvent *event) override
{
QWidget::paintEvent(event);
QPainter p(this);
const int itemHeight = fontMetrics().height();
const int itemTopMargin = 15;
const int xOffset = 15;
int y = itemHeight;
for (size_t i = 0; i < 5; ++i) {
// The angle is in range [-40, 40]. Remove " * 4" for [-10, 10].
const int rsc = (10 - 5 * i) * 4;
qDebug() << i << ":\t" << rsc << "\t" << y;
/*
Rotation must be performed relative to central point of the
drawn item. Transformations below are applied in reverse order.
At first translate item to make it's center in (0, 0). At
second rotate it relative to X axis. At third move the item to
desired position.
*/
QTransform transform;
transform.translate(xOffset, y + itemHeight / 2);
transform.rotate(rsc, Qt::XAxis);
transform.translate(0, - itemHeight / 2);
p.setTransform(transform);
p.drawText(QPoint(), QString("(Item no. %1)").arg(i + 1));
y += itemHeight + itemTopMargin;
}
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MyWidget widget;
widget.setMaximumSize(200, 250);
widget.show();
return app.exec();
}
这里使用的转换很复杂,因为需要相对于它的中心旋转每个项目 y
,而不是 y = 0
。也可能是这样。
增加了字体和角度以更好地查看考虑的效果。