[Solved] Setting font has no effect in QGraphicsItem subclass paint() method



  • My custom drawing of a QGraphicsItem includes text using user-configurable fonts (previously picked with QFontDialog).

    Attempting to assign the font to either the provided QPainter OR to the QGraphicsScene within my subclass' QGaphicsItem::paint() method has no effect. The plan is to render a few different text pieces using distinct fonts. Is it possible to do this in QGraphicsItem::paint()? (virtual method override). [See code excerpt below].

    I know I could deploy child QGraphicsTextItems or QGraphicsSimpleTextItems. I will if I have to. (Do I have to?).

    (We're using Qt 4.8.5 on Windows).

    @QFont _labelFont;
    const QString labelFontStr = labelFontName();
    _labelFont.fromString (labelFontStr);

    // virtual from QGraphicsItem
    void TeacupGfxItem::paint (QPainter* painter,
    const QStyleOptionGraphicsItem* /options/,
    QWidget* /widget/ /=NULL/)
    {
    // ... ... ...

    // *** NEITHER OF THESE HAVE ANY EFFECT ***
    painter->setFont (_labelFont);
    scene()->setFont (_labelFont);

    const QString labelStr = teacupLabelStr();
    static const int textFlags = Qt::AlignHCenter | Qt::AlignTop |
    Qt::TextDontClip | Qt::TextSingleLine;
    QRectF drawnBoundRect;
    painter->setPen (QPen (Qt::black));
    painter->drawText (_labelRect, textFlags, labelStr, &drawnBoundRect);
    }@



  • Can you try this and see what is the issue in your code ?

    @void TeacupGfxItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
    painter->drawLine(20,30,20,200);
    QFont serifFont("Times", 30, QFont::Bold);
    painter->setFont(serifFont);
    painter->drawText(QPoint(),"http://www.pthinks.com");

    }
    @



  • I rarely use setFont and drawText directly (for performance reasons), but I've never had any problems with the font when I did.

    Things to check:

    • Step into the drawText, and verify that the painter's font is still what you set
    • Check that the font actually exists on your system, otherwise a fallback font might be used


  • Dheerendra, that was a smart thing to try ... your example above (with " http://www.pthinks.com " sample text). (See what I did there). It worked also with the QPainter::drawText() overload I was using -- one having an initial const QRectF& rectangle parameter).

    I'm apparently having a problem with my formulation of my QFont _labelFont field -- which I will figure out.

    Calling QPainter::setFont() within a QGraphicsItem::paint() implementation -- with a valid QFont instance -- IS WORKING for me. Thank you.



  • Asperamanca, thanks for your comment. (And quite right too -- I am having a problem with my QFont -- see prior post).

    I'm curious -- WHAT WOULD be the best performance solution for complex QGraphicsItems having several text "pieces"? (in the Qt C++ QWidget / QGraphicsScene world).

    I understand that using child text items -- e.g. QGraphicsTextItems or QGraphicsSimpleTextItems -- would incur the the SAME sort of "context switching" (setting the QPainter QFont) which I have in the course of doing the text drawing right in my "teacup" QGraphicsItem's paint() method (PLUS additional overhead). (I believe child QGraphicsItems are painted immediately after the parent item -- there is no global context-switching optimization which is possible in the QML world).

    Asperamanca (or anyone), what would YOU do for optimal QGraphicsItem rendering performance? (Or have you just moved over to Qt Quick / QML)?

    P.S. As vaguely suggested in my code snippet, I am precomputing and caching the QRectF bounding the text piece, for fast implementations of my QGraphicsItem::boundingRect() and QGraphicsItem::shape() virtual method overrides.



  • Regarding performance, the question is: Are you render the same item with the same text, transformations and style (colors, fonts) multiple times, e.g. because of updates to other items?

    If this is the case, there are several ways to improve performance:

    • You can just render the text as you did, but use setCacheMode on your own item.
    • If your item contains both content that changes a lot and text that doesn't, it makes sense to create separate text items, and use setCacheMode on them
    • A bit more low level, you can use QStaticText (though I must admit I found it hard to use, with some unexpected behavior)
    • You can do the caching yourself, render the text into a pixmap, and paint the pixmap


  • I had been mistaken about where the font string was coming from in my application ... i.e. in my call to QFont::fromString (const QString&). That had been an informally formulated CSS Font specification.

    OFF TOPIC: It would be nice if QFont had possibly-heuristic (if necessary) encode/decode methods for CSS Font specifications. Does anything in Qt support that, e.g. Qt Webkit? I don't see anything.

    P.S. I posted this question on a new thread ... "QFont support for CSS Font spec encoding?" ... http://qt-project.org/forums/viewthread/47421/


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.