Results 1 to 9 of 9

Thread: Calling update() from paintEvent()

  1. #1
    Join Date
    Jan 2008
    Posts
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Question Calling update() from paintEvent()

    Hello,

    Calling update() from paintEvent() handler results in interesting behavior under MS Windows (in Mac OS X and Linux everything is ok). For example, I want to make simple animation, like in demos/composition/. For doing animation I will call update() function in the end of paintEvent() handler to force next repaint. In paintEvent() i will use current time to sync animation. This way demos/composition/ works, as I understand.

    It works very good, but when I'm pushing left mouse button down on window caption, animation stops. Animation resumes if I began to drag window. The same situation is with resize. When I release mouse button everything is ok again.

    Calling update() from paintEvent() is just an example. Actually I need to emit some signals from other thread (using QueuedConnection) to GUI thread. But those signals doesn't reach slots when left mouse is down on window caption. But they all will reach slots when I release mouse button. Problem looks the same for me, but the first one is easy to reproduce.

    Anyone know what is going on?

    To reproduce bug you can take examples/widgets/analogclock/. Comment line
    Qt Code:
    1. timer->start(1000);
    To copy to clipboard, switch view to plain text mode 
    in the constructor (AnalogClock::AnalogClock(QWidget *parent))
    in analogclock.cpp. In void AnalogClock:aintEvent(QPaintEvent *) call update() in the end of this function. And the last, make time variable in paintEvent() static, like this:
    Qt Code:
    1. static QTime time(1, 1, 1);
    2. time = time.addSecs(30);
    To copy to clipboard, switch view to plain text mode 
    Thats all.

    actually I don't need any animation. This case is just an example of how to reproduce the situation. I want to know why Qt signal-slot mechanism acts this way when I am pressing left mouse button on window caption. What I really need is to be able to send signals from some thread to GUI thread (yes, via Queued Connection) and to be sure that slots will be called while I am holding this left mouse button down. Now slots will be called for all signals when I will release the mouse button.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Calling update() from paintEvent()

    Why would you call update() from a paintEvent()? It's an obvious misdesign... If you want to make an animation, use a timer or a timerEvent. Triggering a repaint from another repaint is stupid because all you application does is to repaint itself, probably rising CPU usage sky high.

  3. #3
    Join Date
    Jan 2008
    Posts
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Calling update() from paintEvent()

    Calling update() from paintEvent() is just an example. Actually I need to emit some signals from other thread (using QueuedConnection) to GUI thread. But those signals doesn't reach slots when left mouse is down on window caption. But they all will reach slots when I release mouse button. Problem looks the same for me, but the first one is easy to reproduce.
    I don't need it. I don't need any animation at all. This is just an example of what works perfect on Mac and Linux and works bad on Windows. If you want another testcase - run some thread and try to emit signals from it to gui thread using Queued Connection. Slots will be called only when you release the left mouse button.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Calling update() from paintEvent()

    Quote Originally Posted by wonder.mice View Post
    This is just an example of what works perfect on Mac and Linux and works bad on Windows.
    Well, yes. Microwave ovens are not the best sun bath machines either. But hey, they were never meant to be!

    If you do with some Qt component something it wasn't designed for, you do it on your own responsibility. We can only say "you shouldn't do that, it won't work". If you choose to proceed, you do it at your own risk.

    As for your other doubt - if the application doesn't have the CPU, it won't process events. If you click on the window decoration which is not a part of the application but rather the windowing system, you might take away CPU from the application and it can't do anything about it. Conclusions are yours to draw.

  5. #5
    Join Date
    Jan 2008
    Posts
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Calling update() from paintEvent()

    You can look on examples\threads\mandelbrot\ to see the effect. On Windows it doesn't updates its content while resizing but on Mac/Linux it does.

  6. #6
    Join Date
    Jan 2008
    Posts
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Calling update() from paintEvent()

    Quote Originally Posted by wysota View Post
    As for your other doubt - if the application doesn't have the CPU, it won't process events. If you click on the window decoration which is not a part of the application but rather the windowing system, you might take away CPU from the application and it can't do anything about it. Conclusions are yours to draw.
    It's nonsense. So you want to say, that when I click on window decoration in Windows everything stopped? =)))) You can take a look on Windows native applications like Clock or Media Player for example - they work even if you click on their caption. More over, slots connected to timer still works in this case. It is very bad design if GUI is dead while user holding mouse button on caption or looking on system menu opened with Alt+Space.

    And if you want calling update() from paintEvent() is implemented in Qt composition demo, so this way is not that bad. BTW.
    Last edited by wonder.mice; 11th January 2008 at 13:09.

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Calling update() from paintEvent()

    Quote Originally Posted by wonder.mice View Post
    It's nonsense. So you want to say, that when I click on window decoration in Windows everything stopped? =))))
    I didn't say that. I only said that if you take the CPU from the application, it won't process events. If those applications you mention do something to prevent it or if Qt application do something that causes it, you might end up observing the effect you have seen.

    More over, slots connected to timer still works in this case.
    Because timer don't grab the mouse while windows and window managers might. Qt acts in this way that if you click on something, it grabs the mouse. Maybe if you click on a decoration, the window manager grabs the mouse preventing mouse events from reaching the application. Maybe your window manager doesn't schedule repaint events to the application while the window is being moved. Either way the application can't process events - it might be that there is nothing to process at all.

    It is very bad design if GUI is dead while user holding mouse button on caption or looking on system menu opened with Alt+Space.
    Yes, I can agree with that.

    And if you want calling update() from paintEvent() is implemented in Qt composition demo, so this way is not that bad. BTW.
    If it is and is not some special case, then it is bad. I can always obscure the window by moving some other window over it and in such a case I don't want my widget to repaint twice (or constantly like in your example).

    BTW. I'm currently looking at the composition example and I don't see a paintEvent reimplemented anywhere and the only call to update() is in setCirclePos() which is fine - the position has changed and so the widget needs to be repainted.

  8. #8
    Join Date
    Jan 2008
    Posts
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Calling update() from paintEvent()

    Quote Originally Posted by wysota View Post
    BTW. I'm currently looking at the composition example and I don't see a paintEvent reimplemented anywhere and the only call to update() is in setCirclePos() which is fine - the position has changed and so the widget needs to be repainted.
    Look at the end of CompositionRenderer::paint() method which is called from paintEvent() (from demos mini-framework that used by many Qt demos)

  9. #9
    Join Date
    Jan 2008
    Posts
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Calling update() from paintEvent()

    I think you don't understand me.

    I need to have way to emit signals from some thread (for example downloads xxx pics from server and wants to notify GUI about how many pics it has downloaded) and to have slots "in GUI thread" that will be called in GUI thread context as handlers of those signals. This works, but on windows when I click on caption or on resize corner GUI stops to receive events (with emitted signals) from other thread, but it can still handle timer events and even paint events if update() was called as slot for timer signal (update() slot connected to some timer). So I can't understand this - when I call update from paintEvent() it not works when mouse is down on caption but when update() called from timer - everything is ok.

    BTW in Qt 4.1.4 we found this problem on Mac too, so it was fixed some where between 4.1.4 and 4.3.2 for Mac platform.

Similar Threads

  1. Replies: 3
    Last Post: 27th November 2006, 09:56

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.