对于Qt4.6.x,如何自动调整文本大小以适应指定的宽度?
在我的QGraphicsRectItem::paint()中,我试图在其rect()中绘制项的名称。但是,对于每个不同的项目,它们可以具有可变的宽度,同样,名称也可以具有可变的长度 目前,我从一个最大字体大小开始,检查它是否适合,并逐渐减小,直到找到适合的字体大小。到目前为止,我还没有找到一个快速简单的方法来完成这项工作。有没有更好或更有效的方法 谢谢对于Qt4.6.x,如何自动调整文本大小以适应指定的宽度?,qt,font-size,autosize,Qt,Font Size,Autosize,在我的QGraphicsRectItem::paint()中,我试图在其rect()中绘制项的名称。但是,对于每个不同的项目,它们可以具有可变的宽度,同样,名称也可以具有可变的长度 目前,我从一个最大字体大小开始,检查它是否适合,并逐渐减小,直到找到适合的字体大小。到目前为止,我还没有找到一个快速简单的方法来完成这项工作。有没有更好或更有效的方法 谢谢 void checkFontSize(QPainter *painter, const QString& name) { // che
void checkFontSize(QPainter *painter, const QString& name) {
// check the font size - need a better algorithm... this could take awhile
while (painter->fontMetrics().width(name) > rect().width()) {
int newsize = painter->font().pointSize() - 1;
painter->setFont(QFont(painter->font().family(), newsize));
}
}
不幸的是,没有。没有简单的解决办法。性能方面最明显的改进是在文本更改时计算并缓存所需的字体大小,而不是在每个事件中重新计算。另一个改进是尝试根据边界矩形的比例估计正确的大小。做出和测试评估应该可以让您更快地纠正大小,而不是简单地每次迭代减少一个点大小。来自qtcentre.org的Johannes提供了以下解决方案:
float factor = rect().width() / painter->fontMetrics().width(name);
if ((factor < 1) || (factor > 1.25))
{
QFont f = painter->font();
f.setPointSizeF(f.pointSizeF()*factor);
painter->setFont(f);
}
float factor=rect().width()/painter->fontMetrics().width(名称);
如果((系数<1)| |(系数>1.25))
{
QFont f=画师->字体();
f、 setPointSizeF(f.pointSizeF()*因子);
画师->设置字体(f);
}
我在我的程序中尝试了一下,到目前为止,它似乎运行得很好。我喜欢它,因为它只需一次就可以产生结果,但它假设字体宽度的比例与其高度相同
您可以将QGraphicsTextItem作为rect项的子项,测量文本项的宽度,然后缩放文本项(setTransform())以适应rect项的宽度(和高度)。这取决于您希望字体大小变化的范围。如果范围较大,则按1递增可能需要很长时间。如果只是几个点大小的问题,速度可能不会成为问题 如果范围较大,另一种方法是增加较大的间隔,而不是“1”。如果您在一个步骤中超过了所需的大小,请将间隔减少一半。你会在最佳尺寸上来回弹跳,每次弹跳的幅度越来越小;当两个连续间隔之间的差值很小时,您可以退出 这类似于根查找中使用的方法。这可能有点过分,因为在给定的应用程序中可以接受的字体大小可能相当窄,并且您已经使用的暴力方法不会占用太多时间。
void myClass::AdapterFontSize(qPaint*painter、int标志、QRectF drawRect、QString文本){
void myClass::adaptFontSize(QPainter * painter, int flags, QRectF drawRect, QString text){
int flags = Qt::TextDontClip|Qt::TextWordWrap; //more flags if needed
QRect fontBoundRect =
painter->fontMetrics().boundingRect(drawRect.toRect(),flags, text);
float xFactor = drawRect.width() / fontBoundRect.width();
float yFactor = drawRect.height() / fontBoundRect.height();
float factor = xFactor < yFactor ? xFactor : yFactor;
QFont f = painter->font();
f.setPointSizeF(f.pointSizeF()*factor);
painter->setFont(f);
}
int flags=Qt::TextDontClip | Qt::TextWordWrap;//如果需要,请提供更多标志
QRect fontbundrect=
画师->fontMetrics().boundingRect(drawRect.toRect(),标志,文本);
float xFactor=drawRect.width()/fontbundrect.width();
float yFactor=drawRect.height()/fontBoundRect.height();
浮动系数=xFactor字体();
f、 setPointSizeF(f.pointSizeF()*因子);
画师->设置字体(f);
}
或者更准确但贪婪
void myClass::adaptFontSize(QPainter * painter, int flags, QRectF rect, QString text, QFont font){
QRect fontBoundRect;
fontBoundRect = painter->fontMetrics().boundingRect(rect.toRect(),flags, text);
while(rect.width() < fontBoundRect.width() || rect.height() < fontBoundRect.height()){
font.setPointSizeF(font.pointSizeF()*0.95);
painter->setFont(font);
fontBoundRect = painter->fontMetrics().boundingRect(rect.toRect(),flags, text);
}
}
void myClass::AdapterFontSize(QPaint*painter、int标志、QRectF rect、QString文本、QFont字体){
QRect-fontbundrect;
fontBoundRect=画师->fontMetrics().boundingRect(rect.toRect(),标志,文本);
而(rect.width()设置字体(字体);
fontBoundRect=画师->fontMetrics().boundingRect(rect.toRect(),标志,文本);
}
}
分而治之:
您可以减少蛮力方法中的传递次数:
假设您的首选(最大)字体大小为40,最小字体大小为0
如果(40==false&&0==true)
- 20=真//用每个猜测将可能性一分为二
- 30=错误
- 25=正确
- 27=正确
- 28=错误
- 所以27胜
void scalePainterFontSizeToFit(QPainter&painter,QFont&r_字体,float_字体高度)
{
浮动oldFontSize、newFontSize、oldHeight;
//初始化
oldFontSize=r_font.pointSizeF();
//环路
对于(int i=0;i跟随函数
void scalePainterFontSizeToFit(QPainter &painter, QFont &r_font, float _heightToFitIn)
{
float oldFontSize, newFontSize, oldHeight;
// Init
oldFontSize=r_font.pointSizeF();
// Loop
for (int i=0 ; i<3 ; i++)
{
oldHeight = painter.fontMetrics().boundingRect('D').height();
newFontSize = (_heightToFitIn / oldHeight) * oldFontSize;
r_font.setPointSizeF(newFontSize);
painter.setFont(r_font);
oldFontSize = newFontSize;
//qDebug() << "OldFontSize=" << oldFontSize << "HtoFitIn=" << _heightToFitIn << " fontHeight=" << oldHeight << " newFontSize=" << newFontSize;
}
// End
r_font.setPointSizeF(newFontSize);
painter.setFont(r_font);
}
QFont optimizeFontSizeToFitTextInRect(QPainter * painter, QRectF drawRect, QString text, int flags = Qt::TextDontClip|Qt::TextWordWrap, double goalError = 0.01, int maxIterationNumber=10){
painter->save();
QRect fontBoundRect;
QFont font;
double minError = std::numeric_limits<double>::max();
double error = std::numeric_limits<double>::max();
int iterationNumber=0;
while((error > goalError) && (iterationNumber<maxIterationNumber)){
iterationNumber++;
fontBoundRect = painter->fontMetrics().boundingRect(drawRect.toRect(),flags, text);
double xFactor = drawRect.width() / fontBoundRect.width();
double yFactor = drawRect.height() / fontBoundRect.height();
double factor;
if (xFactor<1 && yFactor<1) {
factor = std::min(xFactor,yFactor);
} else if (xFactor>1 && yFactor>1) {
factor = std::max(xFactor,yFactor);
} else if (xFactor<1 && yFactor>1) {
factor = xFactor;
} else {
factor = yFactor;
}
error = abs(factor-1);
if (factor > 1 ) {
if (error < minError) {
minError = error;
} else {
break;
}
}
font = painter->font();
font.setPointSizeF(font.pointSizeF()*factor);
painter->setFont(font);
}
painter->restore();
return font;
}