Impossible to call paintEvent()???



  • I have created a Frame in QT Designer and promoted it to my custom widget, and so far everything I've done with it is completely fine except attempting to call paintEvent();

    I have overidden a bunch of mouse functions which all work, and in these mouse functions I want to call paintEvent();

    @class PaintBox : public QWidget
    {
    Q_OBJECT

    public:
    PaintBox(QWidget *parent);
    ~PaintBox();

    void mouseMoveEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent *e);
    ...
    ...
    @

    @void PaintBox::mouseMoveEvent( QMouseEvent *event )
    {
    repaint();

    //QPaintEvent * e = 0; //I know this is bad code, but its the only bloody way I can call paintEvent :(
    //paintEvent( e);
    }

    void PaintBox::paintEvent( QPaintEvent *e )
    {
    QPainter paint(this);
    getColour();
    paint.setBrush(QColor(_red, _green, _blue));
    paint.drawRect(0, 0, width(), height());
    }
    @

    The mouseMoveEvent() works, but putting repaint() or update() in there NEVER calls paintEvent(). The only way I can seem to call paintEvent is when I resize the window, or I do that aweful workaround I commented out above.

    I also never set setUpdatesEnabled() & setVisible(); these are at their defaults.. even if I do make them true in my code, paintEvent is still never called.

    Appreciate any help, been googling for hours now and to my knowledge repaint() should just work.


  • Moderators

    never call paintEvent() directly. Always use update() to paint in the next event loop iteration or repaint() to paint immediately.

    When you resize your window your rect is drawn like intended in the paintEvent?
    How do you know it is not called in the other cases? Can you please place a debug output int he method and check again...


  • Moderators



  • [quote author="raven-worx" date="1369397201"]never call paintEvent() directly. Always use update() to paint in the next event loop iteration or repaint() to paint immediately.

    When you resize your window your rect is drawn like intended in the paintEvent?
    How do you know it is not called in the other cases? Can you please place a debug output int he method and check again...[/quote]

    I know that the functions are being called because I have breakpoints in both, I see that paintEvent only activates when I resize the window. I have used update() as I mentioned with no success, what exactly do you mean by next event loop iteration? surely every time I enter the mouse function this should happen?

    [quote author="sierdzio" date="1369397433"]Check out "Qt::WA_opaquePainEvent":http://qt-project.org/doc/qt-4.8/qt.html#WidgetAttribute-enum.[/quote]

    I used setAttribute(Qt::WA_OpaquePaintEvent, true); in the class, unfortunately it made no difference in making update() or repaint() calling paintEvent() :(


  • Moderators

    [quote author="Greyze" date="1369399559"]
    I have used update() as I mentioned with no success, what exactly do you mean by next event loop iteration? surely every time I enter the mouse function this should happen?[/quote]
    You need to understand what the "Qt event loop":http://doc.qt.digia.com/qq/qq11-events.html is. But basically it is called with a short delay when you use update().

    And your event handlers should be protected instead of public!!


  • Moderators

    Edit: deleted due to double post.



  • [quote author="raven-worx" date="1369399904"][quote author="Greyze" date="1369399559"]
    I have used update() as I mentioned with no success, what exactly do you mean by next event loop iteration? surely every time I enter the mouse function this should happen?[/quote]
    You need to understand what the "Qt event loop":http://doc.qt.digia.com/qq/qq11-events.html is. But basically it is called with a short delay when you use update().

    And your event handlers should be protected instead of public!!

    [/quote]

    I'm quite sure I understand them, reading that link just tells me what I already knew, and as it says: update() should eventually call paintEvent() and repaint() should force call paintEvent() immediately. And unfortunately neither of these work.

    Unless i'm being really stupid here, I can't see a problem with my code.



  • Ok, Have a look at this example, run it on your machine. Note that the paintEvent() is not called direcdtly but the text is updated every 100 ms. :)

    @class Widget : public QWidget
    {
    public:
    explicit Widget(QWidget * parent = 0)
    : QWidget(parent)
    , mNumber(0)
    , mText(QString::number(mNumber))
    {
    startTimer(100);
    }

    protected:
    void paintEvent(QPaintEvent * event)
    {
    QPainter painter(this);
    painter.drawText(event->rect(), mText);
    }

    void timerEvent(QTimerEvent * /*event*/)
    {
        mText = QString::number(mNumber++);
        update();
    }
    

    private:
    int mNumber;
    QString mText;
    };

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    Widget widget;
    widget.show();
    
    return app.exec();
    

    }@


  • Moderators

    well you said: "what exactly do you mean by next event loop iteration?" ... this seems to me like you do not understand what the event loop is...

    Did you try to make your event handlers protected instead of public as i stated?!



  • @Santosh
    That seems fine, i've also looked at the QT basicdrawing example which overrides paintEvent(); that program functions perfectly of course while my program has practically the same code.. no change :(

    @raven-worx
    Yeah I made the changes, that was silly of me having them as public. Didn't solve the problem however :(


  • Moderators

    can you share the whole project? There has to be something wrong in your code which you didn't have posted yet...



  • I've stripped down my project just to the barebones of this problem a link to a zip file is here: "http://sdrv.ms/13PKSnG":http://sdrv.ms/13PKSnG

    The project is based on QT 4.8.4, and is built for Visual studio 2012, to run in VS2010 you need to change Platform Toolset to "v100" in the project properties (general).

    I'm trying to create a colour sampler.
    The pixel colour of the mouse position is taken and used to colour the frame on the form.
    The code to take the pixel colour is WIN32 and is 100% functional.
    When the app is running, the colour is taken whenever you click outside of the window, doing this calls a function to my QWidget, which in turn calls update().
    You can see the colour code working by resizing the window, or minimizing/maximizing the window as QT by default calls paintEvent when these actions happen.

    Thanks btw!



  • You missed to call the base class QMainWindow::event() in the ColourSampler::event(), which will cause the whole QObject (and QWidget) events to be blocked, and hence re-painting is also blocked.

    Here are the recommended changes

    @bool ColourSampler::event(QEvent event)
    {
    /

    if (event->type() == QEvent::WindowDeactivate)
    {
    forceUpdate();
    }
    */
    if (event->type() == QEvent::ActivationChange)
    {
    if(QApplication::activeWindow() != this)
    {
    forceUpdate();
    this->show();
    }
    }

    return QMainWindow::event(event); //<<<<<<<<<<<<<<
    

    }

    void PaintBox::attemptRepaint()
    {
    getColour();
    update();
    }

    void PaintBox::paintEvent( QPaintEvent * event)
    {
    QPainter paint(this);
    paint.setBrush(QColor(_red, _green, _blue));
    paint.drawRect(0, 0, width(), height());
    }@



  • blurrrrrrrrrghhhhhhhhhhh

    I removed that code a while back.. haven't got a clue why I did that.

    Thanks very much for the help!

    /high five to all!


Log in to reply
 

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