居中的单词包裹kerned文本

时间:2011-11-06 17:31:58

标签: c++ qt

我正在创建一个自定义控件,并希望使其足够通用以使用任何方向。当我尝试垂直方向时,kerned文本不居中。 您可以通过附加图像中的字符“i”看到最佳效果。 有什么建议吗?

centering kerned text

以下是我渲染文字的方式:

  int flags = Qt::AlignJustify | Qt::AlignVCenter | Qt::TextWrapAnywhere;
  painter.drawText( TextArea, flags, text );

画家是QPainter。此代码位于paintEvent()方法中。

2 个答案:

答案 0 :(得分:3)

我不认为有一个Qt功能可以达到你想要的效果。但是你可以逐个字母地画它。您可以这样做:

 QFontMetrics fm = painter.fontMetrics();
 QString t = "Sample";

 // Loop through all letters
 int topX = 5;
 int topY = 5;
 int yOffset = 0;

 for (unsigned i=0; i<t.count(); i++)
 {
   QChar c = t.at(i);
   // Get metrics
   int w = fm.width(c);
   int h = fm.height();

   painter.drawText(topX-w/2, topY-h/2, QString("%1").arg(c));

   topY = topY + h + yOffset;
 }

工作原理

  • 获取字体指标以计算每个字母的宽度和高度。
  • topX, topY是画家坐标中第一个字母的中心坐标
  • yOffset是字母之间的垂直距离
  • 为所有字母获取其宽度和高度。
  • 将它们绘制在正确的位置。因为在绘制文本时我们给出了它的左上角位置,所以我们将它放在它的中心位置,以便让它居中
  • 将topY增加前一个字母的高度和y偏移量
  • TODO:检查绘制的文本是否在小部件的边界内......

修改

在给定矩形内绘制文本的第二种方法:

  • 将初始矩形拆分为n个子矩形,其中n为提供的字符串中的字母数。
  • 将每个字母绘制到相应子矩形的中心
  • 此方法的优点是文本在给定的边界矩形内绘制,因此它可以适合垂直控件......

示例代码:

/* Let rect the rectnagle in which we want to draw the vertical text
and t the string we are drawing. rectH is the height of every sub-rectangle */
double rectH = rect.height() / (double) t.count();
for (unsigned i=0; i<t.count(); i++)
{
     QChar c = t.at(i);

     // Draw every char in the corresponding sub rectangle
     painter.drawText(QRect(rect.topLeft().x(),
                rect.topLeft().y() + i*rectH,
                rect.width(),
                rectH),
              Qt::AlignCenter,
              QString("%1").arg(c));

}

希望它有所帮助...

答案 1 :(得分:1)

在每个角色后面添加换行符可能会有效。

<强>更新

另外,我认为你应该删除Qt::AlignJustify标志。之前我没有注意到你错过了水平定心旗。试试这些标志:

int flags = Qt::AlignVCenter | Qt::AlignHCenter | Qt::TextWrapAnywhere;

int flags = Qt::AlignCenter | Qt::TextWrapAnywhere;