qt - QPainter::rotate 具有非垂直角度会导致波浪线
qt - QPainter::rotate with non-perpendicular angles causes wiggly lines
我正在尝试以非垂直角度(即 0 到 90 之间)在小部件上绘制文本。绘制文本本身没有问题,但生成的文本非常 wiggly/unevenly 绘制.
在下图中,我以 45 度角绘制文本行。第一行文字是很多下划线(“_____”),第二行文字是"Multithreading"。此处画下划线而不是直线只是为了突出问题。
如您所见,第一行明显显示文本绘制不均匀。这在第二行中更加微妙,但仍然可见。
以垂直角度(0、90、180 等)绘图不会导致此效果。发生这种情况的原因是什么?
我正在使用 Qt 5.7.0 开发 Windows 10。
最小代码示例:
void MyWidget::paintEvent( QPaintEvent * /* event */ )
{
QFont font;
font.setPointSize( 16 );
font.setStyleStrategy( QFont::StyleStrategy::PreferAntialias );
setFont( font );
QImage image( size(), QImage::Format_ARGB32_Premultiplied );
QPainter imagePainter( &image );
imagePainter.initFrom( this );
imagePainter.setFont( font() );
imagePainter.setRenderHint( QPainter::Antialiasing, true );
imagePainter.eraseRect( rect() );
// Set logical origo in the middle of the image
m_window = QRect(
- width() / 2, // x
- height() / 2, // y
width(), // w
height() // h
);
imagePainter.setWindow( m_window );
m_viewport = QRect(
0, // x
0, // y
width(), // w
height() // h
);
imagePainter.setViewport( m_viewport );
draw( imagePainter );
imagePainter.end();
QPainter widgetPainter( this );
widgetPainter.drawImage( 0, 0, image );
}
void MyWidget::draw( QPainter & painter )
{
painter.save();
// Rotate anti-clockwise
painter.rotate( -m_degrees );
painter.drawText( m_window.top(), 0, tr( "Multithreads" ) );
painter.drawText( m_window.top(), 15, tr( "__________" ) );
painter.restore();
}
我从 this Qt bug ticket 中找到了解决方法。简而言之,解决方法是将文本绘制为 QPainterPath
而不是文本。
修复示例是
// Do this
QPainterPath glyphPath;
glyphPath.addText( x, y, painter.font(), text );
painter.fillPath( glyphPath, painter.pen().color() );
// instead of this
painter.drawText( x, y, text );
编辑:
区别如下图
之前:
之后:
我正在尝试以非垂直角度(即 0 到 90 之间)在小部件上绘制文本。绘制文本本身没有问题,但生成的文本非常 wiggly/unevenly 绘制.
在下图中,我以 45 度角绘制文本行。第一行文字是很多下划线(“_____”),第二行文字是"Multithreading"。此处画下划线而不是直线只是为了突出问题。
如您所见,第一行明显显示文本绘制不均匀。这在第二行中更加微妙,但仍然可见。
以垂直角度(0、90、180 等)绘图不会导致此效果。发生这种情况的原因是什么?
我正在使用 Qt 5.7.0 开发 Windows 10。
最小代码示例:
void MyWidget::paintEvent( QPaintEvent * /* event */ )
{
QFont font;
font.setPointSize( 16 );
font.setStyleStrategy( QFont::StyleStrategy::PreferAntialias );
setFont( font );
QImage image( size(), QImage::Format_ARGB32_Premultiplied );
QPainter imagePainter( &image );
imagePainter.initFrom( this );
imagePainter.setFont( font() );
imagePainter.setRenderHint( QPainter::Antialiasing, true );
imagePainter.eraseRect( rect() );
// Set logical origo in the middle of the image
m_window = QRect(
- width() / 2, // x
- height() / 2, // y
width(), // w
height() // h
);
imagePainter.setWindow( m_window );
m_viewport = QRect(
0, // x
0, // y
width(), // w
height() // h
);
imagePainter.setViewport( m_viewport );
draw( imagePainter );
imagePainter.end();
QPainter widgetPainter( this );
widgetPainter.drawImage( 0, 0, image );
}
void MyWidget::draw( QPainter & painter )
{
painter.save();
// Rotate anti-clockwise
painter.rotate( -m_degrees );
painter.drawText( m_window.top(), 0, tr( "Multithreads" ) );
painter.drawText( m_window.top(), 15, tr( "__________" ) );
painter.restore();
}
我从 this Qt bug ticket 中找到了解决方法。简而言之,解决方法是将文本绘制为 QPainterPath
而不是文本。
修复示例是
// Do this
QPainterPath glyphPath;
glyphPath.addText( x, y, painter.font(), text );
painter.fillPath( glyphPath, painter.pen().color() );
// instead of this
painter.drawText( x, y, text );
编辑:
区别如下图
之前:
之后: