Repaint and paintEvent()

  • I'm very sorry to stress this topic again. In my class I reimplement paintEvent(). At some point I activate some decoration I want to paint onto the widget so I need a repaint. Problem: calling repaint() wont invoke the paintEvent(). Calling paintEvent(NULL) will do the right thing. When resizing the window it also works, in that case the paintEvent will be invoked. So what could be the reason for repaint() not to call the paintEvent? I mean it could be a stupid error, but I just want to know what obvious reasons there could possibly be that the event wont happen. I read it could have to do with the widgets size, but at this point the widget is already visible and should have an assigned size....

    I'm out of ideas...

    Well thanks in advance for some clues

  • Have you tried using update() instead?
    That is the preferred way to trigger paint events unless you absolutely must do the repaint directly.

  • Unfortunately that won't work either. I first tried update and then changed to repaint because it should invoke paintEvent() immediately. But it doesn't, gets never called....

  • Ok
    What triggers the fact that you want a repaint to occur? I mean from where do you call repaint, is it from some kind of event and in that case what?
    Also it might help if we could see some code.

  • Are you sure that your changes happen in a visible area of your widget? AFAIK the update is smart enough to detect if a component really has to be updated.

  • Ok. Well first I run Ubuntu here, if that makes a difference, I sometimes read about slightly different drawing behaviour on different platforms...

    My class is derived from QWidget, lets name it ViewClass. The idea is that it contains a OGRE widget that views some 3D scene. The OGRE widget can be configured in two ways: 2d view - 3d view. Both contain some 3d scene, but when in 2d view the camera is fixed on a plane, well some things in the scene and in the event handling are different then. Additionally when in 2d mode I want to display axes, data ticks and data values around the embedded OGRE widget. This way i can adjust the zoom in the 3d scene and then configure the axes according to it.

    Now there is another class that governs the OGRE widget and the painting of the axes -> AxisDecorator. This is no Qt class, it just governs where the OGRE widget is placed in ViewClass and how the axes are painted on it. When switching from 3d to 2d mode I call ViewClass::showAxisDecoration() which will call AxisDecorator::show(true) which will invoke the painting of the axes in my paint event. Then I call repaint() and expect a paint event to happen.
    The paintEvent() looks like

    void ViewClass::paintEvent( QPaintEvent
    e )
    //never called

    QPainter painter( this );
    axis_dec_->update( &painter ); //adjust OGRE widgets position and size according to some 
                                               //precalculations and paint the axes around it
    ogre_widget_->aspectFromViewport(); //adjust scene aspect to new window size
    ogre_widget_->updateView(); //update OGRE widgets view, render etc.


    void ViewClass::showAxisDecoration( bool show )
    axis_dec_->show( show );


    showAxisDecoration() is called from a SLOT that is triggered by some GUI button.
    I know this is very few code, problem is that I can't just post all of it and I'm not sure how to compile a smaller example from it that is equivalent... I will try to add code if needed, but what would interest me is in which ways repaint() won't call my paintEvent at all.

    I know:

    • If the geometry is not set
    • If the widget is not visible
    • If updates are not enabled

  • I am not quite sure but I think that's exactly what I tried to say before. Qt does not know that "something else" changed and that's why it is not repainting your window. Don't you have an update function for your external class?
    As a workaround for the moment to try, just paint a 0 length line which you can turn on and off by the axis boolean and see what happens.

  • "Are you sure that your changes happen in a visible area of your widget?"

    Does that matter if the paintEvent() is never called? I thought that repaint() will result in a paintEvent() anyway. My changes never happen since they are painted inside the paintEvent() which is not called. Or I am missing something...


  • "just paint a 0 length line which you can turn on and off by the axis boolean and see what happens"

    Am I not supposed to do this INSIDE the paintEvent()? When using a painter on the widget from outside paintEvent() Qt will give a warning...

    I will hack around this one by calling paintEvent(NULL) or doing a resize, don't know, but it seems very strange to me, I don't get it.... argh!

  • I have this exact same issue, my Widget only repaints if I issue a resize or manually resize the widget

Log in to reply

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