【问题标题】:Qt: Antialiasing of vertical text rendered using QPainterQt:使用 QPainter 渲染的垂直文本的抗锯齿
【发布时间】:2015-06-25 06:59:19
【问题描述】:

我已经实现了一个类似于这个例子的定向 QPushButton(在我的例子中是一个绘图的轴标签): Vertical QLabel, or the equivalent? 这是当前的paintEvent:

void OrientedPushButton::paintEvent(QPaintEvent* ev) {

if (mOrientation == Qt::Vertical) {

    QPainter p(this);

    // support focus/hover styles
    QStyleOption opt;
    opt.init(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);

    // text render hint
    p.setRenderHints(QPainter::TextAntialiasing);
    p.rotate(-90);

    QRect r(0, 0, -height(), width());
    p.drawText(r, Qt::AlignHCenter | Qt::AlignVCenter, QPushButton::text());
}
else    // default drawing for horizontal buttons
    QPushButton::paintEvent(ev); 
}

渲染的 QPushButton 如下所示:

尤其是“A”,可以看到垂直的 QPushButton 渲染得更清晰。有没有办法渲染垂直文本,以便应用与水平文本相同的抗锯齿?

[编辑] 我尝试了@PavelStrakhov 提出的像素图渲染,虽然这种方法对垂直文本应用了抗锯齿,但它不能解决清除类型问题:

【问题讨论】:

  • 尝试添加p.setRenderHint(QPainter::Antialiasing);
  • 如果您手动渲染水平文本(而不是使用默认实现),它是否正确应用抗锯齿?
  • @Milovidov 和 p.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing); 不能解决问题
  • @PavelStrakhov 感谢您添加图片。如果我自己渲染水平文本(没有p.rotate(-90);),抗锯齿与QPushButton::paintEvent(ev); 相同。

标签: c++ qt


【解决方案1】:

this question 也解决了这个问题,似乎(还)没有一致的跨平台解决方案。您可以创建像素图并在其上水平绘制文本,然后旋转像素图并将其绘制在小部件上:

QPixmap pixmap(size());
pixmap.fill(Qt::transparent);
QPainter p2(&pixmap);
p2.setRenderHints(QPainter::TextAntialiasing);
p2.drawText(pixmap.rect(), Qt::AlignHCenter | Qt::AlignVCenter, 
            QPushButton::text());
p2.end();
pixmap = pixmap.transformed(QTransform().rotate(-90));
#todo: cache pixmap
#...
p.drawPixmap(rect(), pixmap);

创建和旋转像素图是一项相对昂贵的操作,不应在每次重绘时进行。但是您可以将其存储在QCache 中,或者在第一代之后仅存储在成员变量中。

【讨论】:

  • 感谢您的提示。相关问题,尤其是wiki 文章带来了更多见解。不幸的是,像素图渲染并不能解决问题(文本变得非常模糊) - 现在在我看来,最好等待 4K 显示器。
【解决方案2】:

我遇到了类似的像素图渲染问题。当我使用 QPainter 在像素图上绘制文本时,结果像素图模糊不清,质量低下。在对 Qt 源代码进行一些调查之后,我通过在调用painter.drawText(...) 之前找到系统设备像素比率并将其设置在像素图上来解决了这个问题。

    /*
     * The following code is to avoid low quality blur pixmap created via
     * QPainter, sample code is found in QAbstractItemViewPrivate::renderToPixmap method
     */
    qreal scale = 1.0;
    QWidget *window = this->window();
    if (window) {
        QWindow *windowHandle = window->windowHandle();
        if (windowHandle) {
            scale = windowHandle->devicePixelRatio();
        }
    }
    QPixmap pixmap(pixmapRect.size() * scale);
    pixmap.setDevicePixelRatio(scale);

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多