简体   繁体   English

QFont的有效PointSize

[英]Valid PointSize for QFont

I have a QOpenGLWidget in which I draw text with a QPainter. 我有一个QOpenGLWidget,其中使用QPainter绘制文本。 I would like to implement a snapshot feature by rendering the widget content into a QOpenGLFrameBuffer and converting the frame buffer into a QImage. 我想通过将小部件内容呈现到QOpenGLFrameBuffer并将帧缓冲区转换为QImage来实现快照功能。

Unfortunately, if I set the font's point size too high (> 46), the text appears as a black bar in the snapshot, while in the widget it is displayed correctly. 不幸的是,如果我将字体的磅值设置得太大(> 46),则文本在快照中显示为黑条,而在小部件中则正确显示。 See below an example snapshot where the block over the line is supposed to be text with font size > 46. 参见下面的示例快照,其中该行的块应该是字体大小> 46的文本。 黑线上方的方块应该是一些文字

Here is the simplified code to render the image (it should work, because it is correctly displayed in the QOpenGLWidget): 这是渲染图像的简化代码(它应该起作用,因为它已正确显示在QOpenGLWidget中):

void renderSomething(const int x, const int y, const QString & str, const int fontSize) {
    // 1. draw the line
    // (calculate min_x, max_x, y and z values)
    glLineWidth(3);
    glColor3f(0., 0., 0.);
    glBegin(GL_LINES);
    glVertex3f(min_x, y, z);
    glVertex3f(max_x, y, z);
    glEnd();

    // 2. draw the text
    GLint gl_viewport[4];
    glGetIntegerv(GL_VIEWPORT, gl_viewport);
    backup_gl_state();
    QOpenGLPaintDevice paintDevice(gl_viewport[2], gl_viewport[3]);
    QPainter painter(&paintDevice);
    painter.setFont(QFont(painter.font().family(), fontSize);
    painter.setPen(Qt::black);
    painter.drawText(x, y, str);
    painter.end();
    restore_gl_state();
}

Here is the code for storing a snapshot: 这是用于存储快照的代码:

void Viewport::takeSnapshot(const QString & path, const int size) {
    glPushAttrib(GL_VIEWPORT_BIT);
    glViewport(0, 0, size, size); // since size varies I want the text to scale with it
    QOpenGLFramebufferObject fbo(size, size, QOpenGLFramebufferObject::Depth);
    fbo.bind();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    renderer.renderSomething(100, 100, "Test", 50); // Here is the render call!

    QImage fboImage(fbo.toImage());
    QImage image(fboImage.constBits(), fboImage.width(), fboImage.height(), QImage::Format_RGB32);
    image.save(path);
    glPopAttrib();
    fbo.bindDefault();
    fbo.release();
}

EDIT 编辑

I found a workaround by using QPainter to directly draw the text on the QImage instead of drawing into the FBO. 我通过使用QPainter直接在QImage上绘制文本而不是将其绘制到FBO中找到了解决方法。 No black bar anymore, but it complicates my code and I would be happy to find a real solution... 不再有黑条,但它使我的代码变得复杂,我很乐意找到真正的解决方案...

The solution was simple: Re-read the documentation on QOpenGLFrameBufferObject in which it says: 解决方案很简单:重新阅读有关QOpenGLFrameBufferObject的文档 ,其中说:

Create the QOpenGLFrameBufferObject instance with the CombinedDepthStencil attachment if you want QPainter to render correctly. 如果希望QPainter正确呈现,请创建带有CombinedDepthStencil附件的QOpenGLFrameBufferObject实例。

I only attached a depth buffer. 我只附加了一个深度缓冲区。 The correct initialization would be: 正确的初始化为:

QOpenGLFramebufferObject fbo(size, size, QOpenGLFramebufferObject::CombinedDepthStencil);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM