Nominate our 2022 Qt Champions!

QPainter strange behavior

  • Hi All,

    I'm getting strange behavior from a QPainter.

    Without typing a huge message here is my organization:

    I have a QDialog displayed. On that dialog I have a single vertical layout.

    I created a small widget which derives from QWidet. In the paint event of this widget I graph some data. The code in the paint event is:

      QColor drawColor(255, 0, 0);
      QBrush backColor( QColor( 0, 0, 0 ) );
      QPainter painter(this);;
      painter.setBackground( backColor );
      painter.setBrush( backColor );
      QRect wr = geometry();
      painter.drawRect( wr );
      painter.drawText( 10, 10, QString("PAN:%1-%2").arg(GetIdAsHexString()).arg(m_framecount++) );
     // draw the data with painter.drawLine calls

    In my dialog I can add multiple Widgets (for multiple graphs). The code for this is:

    obj = new GraphDisplayWidget(id);
    ui->loPanVertical->addWidget( obj );

    The issue is with the lines to get the rectangle and draw the rectangle in black. above. The issue is that for the first GraphDisplayWidget I add the graph is drawn in red over a black background as desired. But if I add a second widget or third, the graph is fine but the background is not set to black. See this image:

    I'm trying to figure out why. The code is identical for all three widgets. I was thinking that perhaps the vertical layout which contains the widgets is some how only allowing the background to be set once. So I tried creating vertical layouts on the fly but get the same result.

    Any ideas?

  • Lifetime Qt Champion

    @SysTech said:

    Yes sounds odd, but

    I was wondering :

    QRect wr = geometry();
    painter.drawRect( wr );

    This would give the x,y of the widget relative to the parent.
    So on first box which is at 0,0, it matches up with the widget inner coordinates.
    But next one is not at x,y and then its outside of the inner coordinates and hence
    dont clear at all and u see default color.

    Try with
    QRect wr(0,0, width(), height());

  • @mrjj

    Come to think of it you might be spot on!!! Let me try that.

  • @mrjj

    Yep that was exactly it. Thank you again!!!

  • Moderators

    One more thing, why not set the background color directly to the widget? As it's now, the Qt runtime will erase the widget once, and then hand it to you in the paint event, where you erase it a second time.

  • @kshegunov

    Ok that is a great idea... How?

    Are you suggesting I do this when created?

  • Moderators

    Well, I mistakenly thought that you can set the color (not the background role), however my sentiment was (somewhat) correct. You can disable Qt filling your background by setting the auto fill property to false. Alternatively, or even a preferred way, since you're painting the whole widget you can set the Qt::WA_OpaquePaintEvent attribute, which should provide some improvement to painting as well.

    Are you suggesting I do this when created?

    You can set either the property or the attribute in the GraphDisplayWidget constructor.

  • @kshegunov

    Awesome! I'll give it a try!

Log in to reply