Results 1 to 19 of 19

Thread: Not updating while painting in QMdiArea

  1. #1
    Join Date
    Apr 2008
    Posts
    26
    Thanks
    1

    Default Not updating while painting in QMdiArea

    Hello All.

    My task is to connect to MDI sub windows with a line. Im calculating coordinates of my windows, save them and then drawing a line in the QMdiArea->viewport() using QPainter in reimplementation of paintEvent.
    The problem is Qt repaints only those parts of QMdiArea that are under my child windows, and i need whole viewport to be repainted to update my line as well when moving child windows i.e. QPaintEvent->rect() = my child form size and position, not viewport()->rect().

    So how do i force Qt to repaint whole viewport how it is done in simple widgets instead of child windows parts?

    Thanks in advance.

  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: Not updating while painting in QMdiArea

    paintEvent() of which object do you reimplement?

  3. #3
    Join Date
    Apr 2008
    Posts
    26
    Thanks
    1

    Default Re: Not updating while painting in QMdiArea

    1. I made a class
    MyQMA: public QMdiArea
    {
    ...
    protected:
    void paintEvent(QPaintEvent* pe)
    {
    QPainter p(this->viewport());
    p.drawLine(QPoint(X1,Y1),QPoint(X2,Y2)); //X1,Y1,X2,Y2 - sub windows coords
    }
    ...
    }

    2. And within this paintEvent pe->rect() = MyQMA->rect() only if mouse pressed and moved within the MDI. But if i move child window or take some other window over my application pe->rect() = MySubwindow->rect(). And connecting line is painted correctly only if i press and move mouse, not if i move child MDI subwindow.

  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: Not updating while painting in QMdiArea

    I guess the best solution is to apply an event filter on all sub windows, so that you are notified when they get moved. Then you can update() the mdi area's viewport which should trigger the paintEvent properly.

  5. #5
    Join Date
    Apr 2008
    Posts
    26
    Thanks
    1

    Default Re: Not updating while painting in QMdiArea

    So it isnt possible to force QMdiArea:aintEvent() to update whole area whenever QMdiArea:aintEvent() called?

    And the solution is to implement new MDI widget that inherits QWidget by myself
    Or to call update() in all events like moving windows, adding new windows, deleting old etc?

  6. #6
    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: Not updating while painting in QMdiArea

    Quote Originally Posted by rippa View Post
    So it isnt possible to force QMdiArea:aintEvent() to update whole area whenever QMdiArea:aintEvent() called?
    I think the problem is that the paint event is not called at all, not that it is called with wrong parameters. At least that's what I understood from what you have written.

    And the solution is to implement new MDI widget that inherits QWidget by myself
    Or to call update() in all events like moving windows, adding new windows, deleting old etc?
    As I said, installing an event filter and manually triggering update() should be enough. There is no need to reinvent the wheel.

  7. #7
    Join Date
    Apr 2008
    Posts
    26
    Thanks
    1

    Default Re: Not updating while painting in QMdiArea

    Quote Originally Posted by wysota View Post
    I think the problem is that the paint event is not called at all, not that it is called with wrong parameters. At least that's what I understood from what you have written.
    Its surely called Both times.
    It is called when i move child window and it is called when i press/move mouse in the mdi area. I cout << pe->rect << both times and see that second time it updates whole MDI window, but first time it updates only area under my moving sub window.

    Quote Originally Posted by wysota View Post
    As I said, installing an event filter and manually triggering update() should be enough. There is no need to reinvent the wheel.
    Yes, i thought about this solution but its not so convinient because MDI need to be updated not only when subWindows move but in some different cases. And paintEvent() is actually CALLED when windows move so it wont help i think, but ill try. Thanks anyway.

    I thought there must be something like widget(paint engine) property that sets whether paintEvent should update whole widget or not. It would have been much easier and logical imho.
    Or maybe overriding QPaintEvent* that passed to paintEvent() function, or something like that.
    Last edited by rippa; 9th April 2008 at 19:01.

  8. #8
    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: Not updating while painting in QMdiArea

    Quote Originally Posted by rippa View Post
    Its surely called Both times.
    So why don't you ignore the rectangle and redraw everything you need?


    Yes, i thought about this solution but its not so convinient because MDI need to be updated not only when subWindows move but in some different cases.
    Why so? You get the event (which in turn has its type) as a parameter to the filter so there is no problem in reacting on wanted events only. Otherwise you'd probably fall into an infinite loop.


    I thought there must be something like widget(paint engine) property that sets whether paintEvent should update whole widget or not. It would have been much easier and logical imho.
    Why do you care about the rectangle so much? Painting is not clipped to the rectangle, is it? Even if it is, you can probably turn clipping off by passing some widget hint while constructing the widget.

  9. #9
    Join Date
    Apr 2008
    Posts
    26
    Thanks
    1

    Default Re: Not updating while painting in QMdiArea

    Quote Originally Posted by wysota View Post
    So why don't you ignore the rectangle and redraw everything you need?
    That is the question ) How do i repaint all?

    Quote Originally Posted by wysota View Post
    Why do you care about the rectangle so much? Painting is not clipped to the rectangle, is it? Even if it is, you can probably turn clipping off by passing some widget hint while constructing the widget.
    In this case while sub windows move painting IS clipped to the rectangle equal to moving subwindow. I think this is done by Qt to optimize painting, since generally there is no additional painting on mdi area besides child windows.
    And that was the question what window hint or what property turns clipping off.

    Quote Originally Posted by wysota View Post
    Why so? You get the event (which in turn has its type) as a parameter to the filter so there is no problem in reacting on wanted events only. Otherwise you'd probably fall into an infinite loop.
    Yes you are right, but this is not the best solution i beleive because in this case painting will be doubled. 1st time from native child window move event (only clipped area) and second time from event filter.
    Much nore logical would be reimplementation QMdiArea:aintEvent() so it updates whole widget or turning clipping off somehow.
    And that is what i asked in 1st post ) HOW?

  10. #10
    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: Not updating while painting in QMdiArea

    Quote Originally Posted by rippa View Post
    That is the question ) How do i repaint all?
    Hmm... I don't understand the question... What do you mean "how"? Using QPainter and drawing in coordinates you want to redraw.

    In this case while sub windows move painting IS clipped to the rectangle equal to moving subwindow. I think this is done by Qt to optimize painting, since generally there is no additional painting on mdi area besides child windows.
    Clipping is certainly not an optimizing technique It's very expensive, so it's turned off in most situations programmers usually don't mess with. Are you sure the painter is clipped? The fact that the event carries a rectangle doesn't yet mean there is actually clipping involved.

    And that was the question what window hint or what property turns clipping off.
    Qt::WA_PaintUnclipped I guess...

    Yes you are right, but this is not the best solution i beleive because in this case painting will be doubled.
    Not necessarily. paintEvents are usually optimized, so there is a chance they'd get optimized here as well.

    Much nore logical would be reimplementation QMdiArea:aintEvent()
    Hmm... isn't it what you did?

  11. #11
    Join Date
    Apr 2008
    Posts
    26
    Thanks
    1

    Default Re: Not updating while painting in QMdiArea

    Quote Originally Posted by wysota View Post
    Hmm... I don't understand the question... What do you mean "how"? Using QPainter and drawing in coordinates you want to redraw.
    But how should i set these coordinates in paintEvent() function? I want to redraw all, but only small rect is redrawn. i cant call update(QRect) in it because it leads to infinite loop.

    Quote Originally Posted by wysota View Post
    Clipping is certainly not an optimizing technique It's very expensive, so it's turned off in most situations programmers usually don't mess with. Are you sure the painter is clipped? The fact that the event carries a rectangle doesn't yet mean there is actually clipping involved.
    I check QPaintEvent::rect() every time paintEvent() called. And its equal to small rectangle = child window. Doesnt that mean that painting is clipped?

    Quote Originally Posted by wysota View Post
    Qt::WA_PaintUnclipped I guess...
    0o, ill try that as soon as i get to work )
    Edit: Tried, doesnt help =(
    Last edited by rippa; 10th April 2008 at 08:36.

  12. #12
    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: Not updating while painting in QMdiArea

    Quote Originally Posted by rippa View Post
    Doesnt that mean that painting is clipped?
    No. It means you can optimize redrawing by changing only the marked rectangle.

  13. #13
    Join Date
    Apr 2008
    Posts
    26
    Thanks
    1

    Default Re: Not updating while painting in QMdiArea

    Anyway.. Nothing helps. Even reimplementation of moveEvent() in my child window. Because Qt puts my child window on its own mdi sub window, which i cant inherit, and move mdi sub window so my child window receive moveEvent only once, when it is created.

  14. #14
    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: Not updating while painting in QMdiArea

    But what exactly is your problem? If you are trying to obtain a paint event with a rectangle containing your whole viewport, then it won't happen and you don't need it. Simply redraw more than the rectangle in your paint event. If you want the whole viewport to be updated, install event filters and call update(void) on the viewport and you'll get a paint event containing the whole viewport if that's important for you.

  15. #15
    Join Date
    Apr 2008
    Posts
    26
    Thanks
    1

    Default Re: Not updating while painting in QMdiArea

    Yes, i need to redraw whole viewport to make my line that connects two sub mdi windows display correctly. You are saying "Simply redraw more than the rectangle".. But how can i do this?? As i can see i cant decide what area to redraw !inside paintEvent()!, Qt decides that by passing QPaintEvent to my paintEvent function.
    And for event filter i cant get move event from MdiSubWindow, as it is created when I do MyQMdiArea->addSubWindow(MySubWidget);. And there is no acces (signals) from this subwindow that i can catch.
    Last edited by rippa; 10th April 2008 at 17:58.

  16. #16
    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: Not updating while painting in QMdiArea

    Quote Originally Posted by rippa View Post
    As i can see i cant decide what area to redraw !inside paintEvent()!, Qt decides that by passing QPaintEvent to my paintEvent function.
    That's not true. The rectangle given by the paint event is only a hint, nothing more.

    Try this:
    Qt Code:
    1. void MyClass::paintEvent(QPaintEvent *pe){
    2. QMDIArea::paintEvent(pe);
    3. QPainter p(viewport());
    4. p.setPen(Qt::red);
    5. p.drawLine(viewport()->rect().topLeft(), viewport()->rect().bottomRight());
    6. p.setPen(Qt::blue);
    7. p.drawLine(pe->rect().topLeft(), pe->rect().bottomRight());
    8. }
    To copy to clipboard, switch view to plain text mode 

  17. #17
    Join Date
    Apr 2008
    Posts
    26
    Thanks
    1

    Default Re: Not updating while painting in QMdiArea

    Quote Originally Posted by wysota View Post
    That's not true. The rectangle given by the paint event is only a hint, nothing more.
    It seems to me that you dont understand what im talking about..
    Please, be good, download simple test project ive attached. Try to move sub windows and u will see what i mean.
    Attached Files Attached Files

  18. #18
    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: Not updating while painting in QMdiArea

    I corrected some of the side mistakes you made and your app was suffering from as well.
    Attached Files Attached Files

  19. The following user says thank you to wysota for this useful post:

    rippa (14th April 2008)

  20. #19
    Join Date
    Apr 2008
    Posts
    26
    Thanks
    1

    Default Re: Not updating while painting in QMdiArea

    Thank you very much. You really helped me.

Similar Threads

  1. Issues updating to QMdiArea
    By fnmblot in forum Qt Programming
    Replies: 9
    Last Post: 17th December 2007, 18:37
  2. QMdiArea unwanted actvation
    By fullmetalcoder in forum Qt Programming
    Replies: 7
    Last Post: 12th November 2007, 07:09

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.