Results 1 to 13 of 13

Thread: Resize QGraphicsScene to the view size at startup

  1. #1
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Resize QGraphicsScene to the view size at startup

    Hi,

    I want to resize the QGraphicsScene to fit the view the first time when the view is shown. However, I can't get it to work.

    I re-implement QWidget::showEvent(), but the first time it gives me wrong geometry.

    Then I re-implement as follwoing, which give warning from time to time about "recursive paint" (not all the times).

    How can I do what I need? Thanks!

    Qt Code:
    1. MyWidget::paintEvent( QPaintEvent* event )
    2. {
    3. static bool firstTime( true );
    4. if ( firstTime ) {
    5. fitSceneToView();
    6. firstTime = false;
    7. }
    8.  
    9. QWidget::paintEvent( event );
    10.  
    11. }
    To copy to clipboard, switch view to plain text mode 

    If I do it in QWidget::event() when QEvent::PolishRequest occurs, it is too late, causing widget to blink.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Resize QGraphicsScene to the view size at startup

    1) Don't modify anything inside paintEvent().

    2) Have you fetched the geometry in showEvent() after passing the event to the base class?

    Cheers,
    _

  3. #3
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Resize QGraphicsScene to the view size at startup

    Quote Originally Posted by anda_skoa View Post
    1) Don't modify anything inside paintEvent().

    2) Have you fetched the geometry in showEvent() after passing the event to the base class?

    Cheers,
    _
    I did as following, and the 1st showEvent gives wrong geometry (very small), the 2nd time the geometry is correct.


    Qt Code:
    1. void MyWidget::showEvent( QShowEvent* event )
    2. {
    3. static bool firstTime( true );
    4. if ( firstTime ) {
    5.  
    6. setupSceneSize( geometry() );
    7.  
    8. firstTime = false;
    9. }
    10.  
    11. QWidget::showEvent( event );
    12. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Resize QGraphicsScene to the view size at startup

    So the answer to my question is "no".

    So my next question would be: why do you expect the widget to have finished reacting to an event that it hasn't gotten a chance to process yet?

    Cheers,
    _

  5. #5
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Resize QGraphicsScene to the view size at startup

    Quote Originally Posted by anda_skoa View Post
    So the answer to my question is "no".

    So my next question would be: why do you expect the widget to have finished reacting to an event that it hasn't gotten a chance to process yet?

    Cheers,
    _
    I thought I did fetch the geometry in the code.

    In setupSceneSize( geometry() ), I got the geometry, pass it to the function, where it tries to set the size of the scene. The 1st time it give wrong geometry.

    It doesn't matter if I call QWidget::showEvent before or after fetching the geometry, same wrong geometry in 1st time.
    Last edited by lni; 10th September 2015 at 19:16.

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Resize QGraphicsScene to the view size at startup

    Quote Originally Posted by lni View Post
    It doesn't matter if I call QWidget::showEvent before or after fetching the geometry, same wrong geometry in 1st time.
    Well, it would definitely not work to fetch it before passing on the event, since then the event has not happened yet as far as the object is concerned.

    You could check if you have more luck with the viewport's show event though.

    Cheers,
    _

  7. #7
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Resize QGraphicsScene to the view size at startup

    I re-implement QGraphicsView::event( QEvent* ) trying to print out the geometry as follows:
    Qt Code:
    1. virtual bool event ( QEvent * evnt ) {
    2. bool result = QGraphicsView::event( evnt );
    3. qDebug() << "event type =" << evnt->type() << ", size =" << geometry().size();
    4. return result;
    5. }
    To copy to clipboard, switch view to plain text mode 

    Here is what I got

    event type = 109 , size = QSize(100, 30)
    event type = 69 , size = QSize(100, 30)
    event type = 69 , size = QSize(100, 30)
    event type = 100 , size = QSize(100, 30)
    event type = 170 , size = QSize(100, 30)
    event type = 97 , size = QSize(100, 30)
    event type = 39 , size = QSize(100, 30)
    event type = 70 , size = QSize(100, 30)
    event type = 70 , size = QSize(100, 30)
    event type = 70 , size = QSize(100, 30)
    event type = 75 , size = QSize(100, 30)
    event type = 69 , size = QSize(100, 30)
    event type = 39 , size = QSize(100, 30)
    event type = 97 , size = QSize(100, 30)
    event type = 97 , size = QSize(100, 30)
    event type = 39 , size = QSize(100, 30)
    event type = 100 , size = QSize(100, 30)
    event type = 68 , size = QSize(100, 30)
    event type = 68 , size = QSize(150, 75)
    event type = 13 , size = QSize(150, 75)
    event type = 14 , size = QSize(150, 75)
    event type = 17 , size = QSize(150, 75)
    event type = 26 , size = QSize(150, 75)
    event type = 18 , size = QSize(150, 75)
    event type = 8 , size = QSize(150, 75)
    event type = 68 , size = QSize(150, 75)
    event type = 68 , size = QSize(1169, 817)
    event type = 14 , size = QSize(1169, 817)
    event type = 17 , size = QSize(1169, 817)
    event type = 9 , size = QSize(1169, 817)
    event type = 67 , size = QSize(1169, 817) // <---- ChildInsertedRequest for QT3_SUPPORT
    event type = 12 , size = QSize(1169, 817) // <---- QPaintEvent
    event type = 74 , size = QSize(1169, 817)
    event type = 43 , size = QSize(1169, 817)
    event type = 43 , size = QSize(1169, 817)
    event type = 71 , size = QSize(1169, 817)
    event type = 71 , size = QSize(1169, 817)
    event type = 43 , size = QSize(1169, 817)
    event type = 43 , size = QSize(1169, 817)
    event type = 76 , size = QSize(1169, 817)
    event type = 71 , size = QSize(1169, 817)
    event type = 71 , size = QSize(1169, 817)
    event type = 43 , size = QSize(1169, 817)
    event type = 43 , size = QSize(1169, 817)

    The correct size is QSize(1169, 817) . The event that gets this size in first time is type 67. But I look at Qt codes, it is defined as

    Qt Code:
    1. #ifdef QT3_SUPPORT
    2. ChildInsertedRequest = 67, // send ChildInserted compatibility events to receiver
    3. ChildInserted = 70, // compatibility child inserted
    4. LayoutHint = 72, // compatibility relayout request
    5. #endif
    To copy to clipboard, switch view to plain text mode 

    Next is type 12, which is QPaintEvent.

    So it looks like I will have to intercept paintEvent( QPaintEvent* ) to set the scene size, but then ocasionally I got recursive painting warning...

    Qt Code:
    1. virtual void paintEvent( QPaintEvent* event ) {
    2.  
    3. if ( m_firstTime ) {
    4. fitView(); // call fitView to set the scene size to fit the view
    5. m_firstTime = false;
    6. }
    7.  
    8. QGraphicsView::paintEvent( event );
    9.  
    10. }
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Resize QGraphicsScene to the view size at startup

    Quote Originally Posted by lni View Post
    I re-implement QGraphicsView::event( QEvent* ) trying to print out the geometry as follows:
    You could also check the viewport events, the QGrahicsView is a QAbstractScrollArea and thus has a view port

    Quote Originally Posted by lni View Post
    event type = 68 , size = QSize(1169, 817)
    event type = 14 , size = QSize(1169, 817)
    event type = 17 , size = QSize(1169, 817)
    event type = 9 , size = QSize(1169, 817)
    event type = 67 , size = QSize(1169, 817) // <---- ChildInsertedRequest for QT3_SUPPORT
    event type = 12 , size = QSize(1169, 817) // <---- QPaintEvent

    The correct size is QSize(1169, 817) . The event that gets this size in first time is type 67.
    Interesting, your posted list says it is 68.

    Quote Originally Posted by lni View Post
    Next is type 12, which is QPaintEvent.
    Interesting, you posted list says it is 14, which is Resize.

    Quote Originally Posted by lni View Post
    So it looks like I will have to intercept paintEvent( QPaintEvent* ) to set the scene size, but then ocasionally I got recursive painting warning...

    Qt Code:
    1. virtual void paintEvent( QPaintEvent* event ) {
    2.  
    3. if ( m_firstTime ) {
    4. fitView(); // call fitView to set the scene size to fit the view
    5. m_firstTime = false;
    6. }
    7.  
    8. QGraphicsView::paintEvent( event );
    9.  
    10. }
    To copy to clipboard, switch view to plain text mode 
    If you do that you need to make sure that fitView() does not change anything in the view or the scene, see earlier in this thread.
    If fitView() does change something, make at least sure it cannot be called twice.
    Better yet call it also delayed.

    Cheers,
    _

  9. #9
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Resize QGraphicsScene to the view size at startup

    Yes, type 68 sees the correct geometry first, but that event type also occurs earlier, so I can't use that type to set up my scene size. Same as type 14. And type 9 is FocusOut, I don't think that event type can be used for my purpose...

    See these output lines:

    event type = 68 , size = QSize(150, 75)
    event type = 14 , size = QSize(150, 75)

    The problem is recursive painting only occurs occasionally, making it very difficult to debug....

  10. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Resize QGraphicsScene to the view size at startup

    The problem is recursive painting only occurs occasionally, making it very difficult to debug....
    Recursive painting will occur any time you do anything in the paintEvent() which triggers an update - resizing, moving, changing graphical properties or almost *anything* else about the appearance the current widget or its children. Don't do it. The paint event should be treated as exactly what it implies: to paint the widget's contents as they existed at the moment the call is made.

    That your recursive repainting occurs only infrequently is pure luck, probably based on timing issues in your own development environment. Move to release mode, move to another faster / slower PC, and you'll see a different and unpredictable set of issues. Don't do it.

    I successfully use showEvent() and resizeEvent() all the time to change scene geometry to match the size of the widget. The resize event will occur multiple times before the widget is shown as a result of the layout system doing its job. You simply check the isVisible() flag before taking any action. It will be false until after the widget is shown.

  11. #11
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Resize QGraphicsScene to the view size at startup

    I think I find out the problem. It should be a Qt bug

    My drawing area is a Mdi subwindow. I call showMaximized() to show the subwindow, which gives me two show events, I have to check isMaximized() to get the correct geometry.

    However, what if the subwindow is not shown using showMaximized, says, first it calls QMdiSubWindow::resize( ... ), then call show(), then my code would break again.

    The problem is within showMaximized(), which call setWindowState( ... ), this triggers showEvent even before show() is called.

    Simply comment out all show methods in following examples, and use w.setWindowState( Qt::WindowMaximized ), the subwindow will still be shown.


    Qt Code:
    1. #include <QApplication>
    2. #include <QMdiSubWindow>
    3. #include <QMdiArea>
    4. #include <QDebug>
    5.  
    6. class MyMdiSubWindow : public QMdiSubWindow {
    7.  
    8. protected:
    9.  
    10. virtual void showEvent( QShowEvent* event ) {
    11. QWidget::showEvent( event );
    12.  
    13. qDebug() << "showEvent: isVisible =" << isVisible()
    14. << ", isMaximized =" << isMaximized()
    15. << ", geom =" << geometry();
    16. }
    17.  
    18. };
    19.  
    20. int main( int argc, char** argv )
    21. {
    22. QApplication app( argc, argv );
    23.  
    24. QMdiArea area;
    25. area.resize( 500, 500 );
    26. area.show();
    27.  
    28. MyMdiSubWindow w;
    29. area.addSubWindow( &w );
    30.  
    31. //w.resize( 100, 100 );
    32. //w.show();
    33. //w.showNormal();
    34.  
    35. //w.setWindowState( Qt::WindowMaximized );
    36.  
    37. w.showMaximized();
    38.  
    39. return app.exec();
    40.  
    41. }
    To copy to clipboard, switch view to plain text mode 

  12. #12
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Resize QGraphicsScene to the view size at startup

    How do I report this bug? I switch to Qt 5.5.0, the same error occurs too.

    "If the window is not visible (i.e. isVisible() returns false), the window state will take effect when show() is called." is NOT true for my test code.

  13. #13
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Resize QGraphicsScene to the view size at startup


Similar Threads

  1. Replies: 1
    Last Post: 29th December 2013, 18:06
  2. Replies: 2
    Last Post: 8th December 2013, 05:53
  3. How to resize a QGraphicsScene to a QGraphicsView?
    By CassioTC in forum Qt Programming
    Replies: 2
    Last Post: 22nd March 2011, 09:03
  4. Replies: 0
    Last Post: 14th February 2008, 12:14
  5. How to resize a QDockWidget when startup the program?
    By heavenstar_x in forum Qt Programming
    Replies: 6
    Last Post: 26th October 2007, 12:58

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.