Results 1 to 6 of 6

Thread: question about size hints and size policies

  1. #1
    Join Date
    Jan 2011
    Posts
    21
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: question about size hints and size policies

    The documentation of the QWidget states
    When implementing a new widget, it is almost always useful to reimplement sizeHint() to provide a reasonable default size for the widget and to set the correct size policy with setSizePolicy().

    By default, composite widgets which do not provide a size hint will be sized according to the space requirements of their child widgets.
    but I am not sure what the second statement actually means.

    Imagine if I have 2 QWidgets. The first QWidget will be set with a Horizontal SizePolicy of QSizePolicy::Maximum. Inside the first QWidget a QTabWidget for instance is created, as a child of that QWidget and new Tabs are added.

    The above statement seems to indicate that, if the custom QWidget (in my case the one that simply creates a TabWidget inside) does not reimplement sizeHint(), the sizeHint will depend on its children, i.e. the TabWidget? However, this does not seem to be the case.

    If I put these 2 QWidgets, the one with the TabWidget inside and its Horizontal SizePolicy of QSizePolicy::Maximum, and an arbitrary other QWidget, with default QSizePolicy, in a QHBoxLayout, the first QWidget will not be visible, since its sizeHint().width() is 0 (or -1?).

    When I implement the sizeHint() of the custom widget, e.g.
    Qt Code:
    1. QSize sizeHint() const
    2. {
    3. return m_tabWidget->size();
    4. }
    To copy to clipboard, switch view to plain text mode 
    everything works of course, but shouldn't this be done automatically?


    Added after 1 32 minutes:


    It looks like the automatic behavior can be achieved by putting the Widget inside the Widget in a Layout.

    However, I am having trouble achieving the same thing for Widgets that use a form from a .ui file.
    Last edited by Spooky; 6th April 2011 at 14:10.

  2. #2
    Join Date
    Jan 2011
    Posts
    21
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: question about size hints and size policies

    Maybe I should provide an example to make it more clear what I mean. Consider this simple Qt App with 2 Widgets. The left widget should only ever be as big as it needs to be while the right Widget should fill the rest of the space (without having to manually screw around with minimum sizes and sizeHint() implementations etc.).
    Qt Code:
    1. MyQtApp::MyQtApp( QWidget *parent, Qt::WFlags flags )
    2. : QMainWindow(parent, flags)
    3. {
    4. // create central widget
    5. QWidget* cw = new QWidget( this );
    6. this->setCentralWidget( cw );
    7.  
    8. // create left widget
    9. QWidget* left = new QWidget( cw );
    10. Ui::MyWidgetForm ui; ui.setupUi( left );
    11.  
    12. // create right widget
    13. QWidget* right = new QWidget( cw );
    14. right->setStyleSheet( "background-color:#FF00FF;" );
    15.  
    16. // create layout in central widget
    17. QHBoxLayout* mainLayout = new QHBoxLayout( cw );
    18. mainLayout->addWidget( left );
    19. mainLayout->addWidget( right );
    20. }
    To copy to clipboard, switch view to plain text mode 
    The .ui file (Ui::MyWidgetForm) has only 2 changes: its horizontal Size Policy changed to Maximum and an added QTabWidget: MyWidgetForm.png

    This results in the right widget taking up all of the space, since the sizeHint of the left Widget is invalid or zero: MyQtApp1.png

    If, on the other hand, I create the UI manually and make a Layout for the left Widget, in which the other Widgets will be stored (in this case just a bare QTabWidget):
    Qt Code:
    1. MyQtApp::MyQtApp( QWidget *parent, Qt::WFlags flags )
    2. : QMainWindow(parent, flags)
    3. {
    4. // create central widget
    5. QWidget* cw = new QWidget( this );
    6. this->setCentralWidget( cw );
    7.  
    8. // create left widget
    9. QWidget* left = new QWidget( cw );
    10. left->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );
    11. QTabWidget* tabWidget = new QTabWidget( left );
    12. tabWidget->addTab( new QWidget, "Tab1" );
    13. tabWidget->addTab( new QWidget, "Tab2" );
    14. QHBoxLayout* leftLayout = new QHBoxLayout( left );
    15. leftLayout->addWidget( tabWidget );
    16.  
    17. // create right widget
    18. QWidget* right = new QWidget( cw );
    19. right->setStyleSheet( "background-color:#FF00FF;" );
    20.  
    21. // create layout in central widget
    22. QHBoxLayout* mainLayout = new QHBoxLayout( cw );
    23. mainLayout->addWidget( left );
    24. mainLayout->addWidget( right );
    25. }
    To copy to clipboard, switch view to plain text mode 
    the sizeHint of the left Widget will be correct and the left Widget will be visible: MyQtApp2.png
    and not expand when its parent Widget gets more space (horizontally): MyQtApp3.png
    Without the added Layout it would be the same behavior as with the .ui version, naturally.


    So, my question is: how can I achieve this with .ui files too? Adding a Layout in the .ui file does not work, since the uic generates a separate QWidget that acts as a parent for the Layout.
    Last edited by Spooky; 7th April 2011 at 09:29.

  3. #3
    Join Date
    Nov 2010
    Posts
    315
    Thanked 53 Times in 51 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: question about size hints and size policies

    1. If widget is complex (has widget children). Widget sizeHint is calculated automatically if you are using a layout. Layout will do calculation of sizeHint based on sizeHint of children.
    2. sizeHint should be implemented only when widget has defined own content (no children). For example QLabel has sizeHint value depending on text it contains.

  4. #4
    Join Date
    Jan 2011
    Posts
    21
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: question about size hints and size policies

    Quote Originally Posted by MarekR22 View Post
    1. If widget is complex (has widget children). Widget sizeHint is calculated automatically if you are using a layout. Layout will do calculation of sizeHint based on sizeHint of children.
    2. sizeHint should be implemented only when widget has defined own content (no children). For example QLabel has sizeHint value depending on text it contains.
    Yep, that's what I figured out now through trial and error. But what about user interfaces that are created via the Qt Designer? As described in my previous post, uic does not generate a generic layout for the content of the Widget. And if you define a Layout manually in the .ui, uic will create another QWidget as the parent of that Layout. And this Widget then has my actual Widget as parent, without being in a Layout and thus, sizeHint will not be calculated anymore, since the Widget created by the uic is not in a Layout.

  5. #5
    Join Date
    Nov 2010
    Posts
    315
    Thanked 53 Times in 51 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: question about size hints and size policies

    You can use layout in designer. Problem is assign a layout to a widget. This can be done but bit tricky because of terrible UI concept of designer in this matter. I don't have Qt creator on this machine so I can't say now what is the correct way for attaching layout to a widget in designer.

  6. The following user says thank you to MarekR22 for this useful post:

    Spooky (7th April 2011)

  7. #6
    Join Date
    Jan 2011
    Posts
    21
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: question about size hints and size policies

    Quote Originally Posted by MarekR22 View Post
    You can use layout in designer. Problem is assign a layout to a widget. This can be done but bit tricky because of terrible UI concept of designer in this matter. I don't have Qt creator on this machine so I can't say now what is the correct way for attaching layout to a widget in designer.
    I don't think there is any special way to do it. Simply drag & drop a Layout and then drag & drop a Widget into the Layout. For instance:

    MyWidgetFormLayout.png

    But the problem is, that the UI compiler generates this code (from that .ui file):
    Qt Code:
    1. class Ui_MyWidgetForm
    2. {
    3. public:
    4. QWidget *verticalLayoutWidget;
    5. QVBoxLayout *verticalLayout;
    6. QTabWidget *tabWidget;
    7. QWidget *tab;
    8. QWidget *tab_2;
    9.  
    10. void setupUi(QWidget *MyWidgetForm)
    11. {
    12. [...]
    13.  
    14. verticalLayoutWidget = new QWidget(MyWidgetForm);
    15. verticalLayoutWidget->setObjectName(QString::fromUtf8("verticalLayoutWidget"));
    16. verticalLayoutWidget->setGeometry(QRect(0, 0, 160, 80));
    17. verticalLayout = new QVBoxLayout(verticalLayoutWidget);
    18. verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
    19. verticalLayout->setContentsMargins(0, 0, 0, 0);
    20. tabWidget = new QTabWidget(verticalLayoutWidget);
    21. tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
    22. tab = new QWidget();
    23. tab->setObjectName(QString::fromUtf8("tab"));
    24. tabWidget->addTab(tab, QString());
    25. tab_2 = new QWidget();
    26. tab_2->setObjectName(QString::fromUtf8("tab_2"));
    27. tabWidget->addTab(tab_2, QString());
    28.  
    29. verticalLayout->addWidget(tabWidget);
    30.  
    31. [...]
    32. } // setupUi
    33.  
    34. [...]
    35. };
    To copy to clipboard, switch view to plain text mode 
    It creates a unique QWidget *verticalLayoutWidget that acts as a parent for the Layout, instead of making the QWidget *MyWidgetForm the parent of the Layout. Even though in the .ui file, the QWidget *MyWidgetForm is clearly the parent of the Layout.

    So instead of something like this:

    Layout1.png


    It is doing something like this:

    Layout2.png


    And thus the sizeHint() of MyWidgetForm will not be calculated, since its children (which is the QWidget* verticalLayoutWidget) are not in a layout.


    Added after 54 minutes:


    Aaah, hang on, now I got what you mean . You have to make your main Widget "layouted". Instead of manually adding a Layout, you have to add your Widget(s) into the Widget and then right click on the Main Widget, go to Lay out and select an appropriate Layout from there.

    MyWidgetFormNotLayouted.png MyWidgetFormLayouted.png

    Now it works as expected, thx!


    This is indeed a little bit tricky, but it's just something you need to know, in order for everything to work as you expect.
    Last edited by Spooky; 7th April 2011 at 12:10.

Similar Threads

  1. Replies: 0
    Last Post: 26th October 2010, 17:59
  2. Replies: 7
    Last Post: 28th May 2009, 23:49
  3. Replies: 1
    Last Post: 10th April 2009, 18:07
  4. Replies: 2
    Last Post: 23rd March 2009, 17:26
  5. Replies: 1
    Last Post: 24th October 2006, 16:40

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.