【问题标题】:QPainter drawText with fractional pointsizesQPainter drawText 小数点大小
【发布时间】:2013-10-02 21:10:48
【问题描述】:

有没有办法在 Qt 5 中绘制小​​数点大小的文本。 我正在尝试使用QFont::setPointSizeF(),但它似乎不适用于我尝试过的任何平台(mac/linux/windows),并且点大小总是四舍五入。

QFontDatabase::isScalableQFontDatabase::isSmoothlyScalable 在所有情况下都会为字体返回 true

我尝试设置各种QFont::fontHintingPreferenceQPainter::RenderHint

我也许可以使用QFont::setPixelSizeQPainter::scale 解决这个问题,但QFont::setPointSizeF 坏了似乎很奇怪?!

我是否遗漏了什么或做错了什么?

显示问题的简单程序:

#include <QtWidgets>

class MyWidget : public QWidget
{
public:
    MyWidget() : QWidget(0)
    {
    }

protected:
    void paintEvent(QPaintEvent */*e*/)
    {
        QPainter p(this);
        int y=10;

        for (qreal i = 10; i < 20; i += 0.2) {
            QFont font("Times"); // or any font font in the system
            font.setPointSizeF(i);
            p.setFont(font);
            p.drawText(1, y, QString("This should be point size %1 but is %2!").arg(font.pointSizeF()).arg(QFontInfo(font).pointSizeF()));
            y += i;
        }
    }
};

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    MyWidget widget;
    widget.resize(400, 740);
    widget.show();
    return app.exec();
}

【问题讨论】:

  • qt4 有同样的问题吗?你在尝试 5.1.1 吗?
  • 在 Mac 上短暂试用过 Qt 4.8,在 mac、linux 和 windows 上试用过 Qt 5.1.1 中的更多内容(对于 windows 尝试过 dl 版本,甚至是支持直接写入的编译版本)
  • 开始使用 scale 和 setPixelSize 是否会变得更好?

标签: c++ qt qt5 qpainter


【解决方案1】:

这不是意外行为。请参阅以下几行:

"This should be point size 10 but is 9.75!"
"This should be point size 10.2 but is 10.5!"
"This should be point size 10.4 but is 10.5!"
"This should be point size 10.6 but is 10.5!"
"This should be point size 10.8 but is 10.5!"
"This should be point size 11 but is 11.25!"
"This should be point size 11.2 but is 11.25!"
"This should be point size 11.4 but is 11.25!"
"This should be point size 11.6 but is 11.25!"
"This should be point size 11.8 but is 12!"
"This should be point size 12 but is 12!"
"This should be point size 12.2 but is 12!"
...

然后,检查文档:

Sets the point size to pointSize. The point size must be greater than zero. The requested precision may not be achieved on all platforms.

【讨论】:

  • "可能无法在所有平台上达到要求的精度。"我在所有 3 个主要平台上都试过了,但它并不适用于所有平台,而且实际上都支持平滑字体缩放(mac 上的 cocoa、windows directwrite/cleartext...)
  • 正如您在结果中看到的那样,它可以并且确实设置了 10.5,为什么它不接受 10.2 和其他小数值?!
  • 这是正常的,据我所知,这就是它应该如何工作的。再次检查文档中的内容。还有,平台很多,你只试了三个。我会说,这没关系。
【解决方案2】:

Qt 似乎根据点大小计算像素大小,最终以 QFont::setPixelSize 为参数,它以 int 作为参数,因此它被四舍五入(或类似的东西)。

所以为了获得更好的精度,我可以这样做:

void paintEvent(QPaintEvent * /*e*/)
{
    QPainter p(this);
    int y=10;

    for (qreal i = 10; i < 20; i += 0.2) {
        QFont font("Times"); // or any font
        font.setPointSizeF(i); // this has round to int error (on 72 dpi screen 10.2 would be rounded to 10 and 10.6 to 11.0 etc)
        p.setFont(font);

        qreal piX = i * p.device()->logicalDpiX() / 72.0;
        qreal piY = i * p.device()->logicalDpiY() / 72.0;
        qreal xscale = piX / qRound(piX);
        qreal yscale = piY / qRound(piY);

        //p.save();
        p.translate(1, y);
        p.scale(xscale, yscale);
        p.drawText(0, 0, QString("This should be point size %1 but is %2!").arg(font.pointSizeF()).arg(QFontInfo(font).pointSizeF() * xscale));
        p.resetTransform();
        //p.restore();
        y += i;
    }
}

这样我可以得到想要的结果。

【讨论】:

  • 您的问题不是如何解决问题,而是您使用的是否错误。你得到了答案,不是吗?你为什么不标记它?还有什么顾虑?
  • 我的问题以“Qt 5 中是否有办法绘制小数点大小的文本”开头?
  • 我不知道它是什么了。你前后变化。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
相关资源
最近更新 更多