Results 1 to 6 of 6

Thread: QScrollArea in a QTabWidget page

  1. #1
    Join Date
    Aug 2011
    Location
    Finland
    Posts
    18
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Arrow QScrollArea in a QTabWidget page

    This should be easy and I found topics similar to this but I'm still stuck, so I'll
    ask in a new thread: How do I get the contents of a tab in a QTabWidget to scroll?

    I create a scroll area, set a layout to it and then insert it to a tab
    widget. Later, I add widgets to that layout. However, scroll bars never
    appear. Instead, the widgets get partially stacked on top of each other.
    What am I doing wrong? I'm trying to avoid having to create a custom
    widget for each and every tab and then using scrollarea->setWidget() but
    is that really the problem?

    Qt Code:
    1. //in header for base class:
    2. protected:
    3. QVBoxLayout* vlayout;
    4.  
    5. //in header for this class:
    6. private:
    7. QTabWidget* tabs;
    8.  
    9. //in constructor for this class:
    10. tabs = new QTabWidget(this);
    11. grid = new QGridLayout();
    12. grid->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    13. QScrollArea* scrollarea = new QScrollArea(this);
    14. scrollarea->setLayout(grid);
    15. tabs->addTab(scrollarea, tr("Look, items!"));
    16. vlayout->addWidget(tabs);
    17.  
    18. //items get added some time after construction:
    19. SomeItem* item = new SomeItem(this); //not derived from base class, does have a layout
    20. item->setStuff("stuff");
    21. grid ->addWidget(item);
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QScrollArea in a QTabWidget page

    Are you trying to achieve:
    • multiple tabs each with content that can be scrolled about, or
    • a single tab with scroll area that grows to accommodate more content added later?

  3. #3
    Join Date
    Aug 2011
    Location
    Finland
    Posts
    18
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QScrollArea in a QTabWidget page

    I don't see the difference between those two points... I will need to have several tabs that each scroll on their own, but once that is established, all of them can receive more items to display. The entire QTabWidget, however, will not need to be viewed through a scrolling area.

    I must say, the interactions between layouts, parent pointers, basic widgets and "container" widgets can get pretty complicated. Very many possible permutations in this case, for example: when to set parent to "this" and when not, what gets added to what and in which order.

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QScrollArea in a QTabWidget page

    I don't see the difference between those two points...
    The difference is that one adds new tabs, and the other adds new content to an existing layout. You talk a bit about adding content to existing layouts but then also talk about having to make custom widgets for each tab. It was worth clarifying whether you wanted one or the other because your code only demonstrates one.
    I will need to have several tabs that each scroll on their own, but once that is established, all of them can receive more items to display. The entire QTabWidget, however, will not need to be viewed through a scrolling area.
    OK, you want both.

    Here is a single tab example:
    Qt Code:
    1. #include <QtGui>
    2. #include <QDebug>
    3.  
    4. class Widget: public QFrame {
    5. Q_OBJECT
    6. public:
    7. Widget(QWidget *p = 0): QFrame(p) {
    8. setFrameStyle(QFrame::Panel | QFrame::Plain);
    9. QVBoxLayout *layout = new QVBoxLayout(this);
    10. layout->addWidget(new QLabel("A Label", this));
    11. layout->addWidget(new QLabel("B Label", this));
    12. setLayout(layout);
    13. }
    14. };
    15.  
    16. class TabWidget: public QTabWidget {
    17. Q_OBJECT
    18.  
    19. QTimer *timer;
    20. QVBoxLayout *layout;
    21. public:
    22. TabWidget(QWidget *p = 0): QTabWidget(p) {
    23. // The stuff inside the scroll area
    24. QWidget *container = new QWidget(this);
    25. layout = new QVBoxLayout(container);
    26. layout->setSizeConstraint(QLayout::SetFixedSize); // <<< this is the magic
    27. addAnother();
    28. addAnother();
    29. container->setLayout(layout);
    30.  
    31. QScrollArea *scroll = new QScrollArea(this);
    32. scroll->setWidget(container);
    33.  
    34. // Put the scrolling area in to a tab page
    35. addTab(scroll, "One");
    36.  
    37. // Cause a new one to be added every 2 seconds for demo purposes
    38. timer = new QTimer(this);
    39. connect(timer, SIGNAL(timeout()), SLOT(addAnother()));
    40. timer->start(2000);
    41. }
    42.  
    43. public slots:
    44. void addAnother() {
    45. layout->addWidget(new Widget(this));
    46. }
    47.  
    48. };
    49.  
    50.  
    51. int main(int argc, char *argv[])
    52. {
    53. QApplication app(argc, argv);
    54.  
    55. TabWidget tw;
    56. tw.show();
    57.  
    58. return app.exec();
    59. }
    60. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 

    The magic is the sizeConstraint on the container's layout. This causes the layout to adopt the size of the contained widget's sizeHint()s rather than resize the contained widgets. For a variation on the theme look at the Extension Example

    In general, if I create a QObject or derived class on the heap I always give it a parent thereby ensuring the memory is freed when the program exits (cleanly or by crashing, not that the latter ever happens to me ).

  5. The following user says thank you to ChrisW67 for this useful post:

    CoderMan (2nd March 2012)

  6. #5
    Join Date
    Aug 2011
    Location
    Finland
    Posts
    18
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Thumbs up Re: QScrollArea in a QTabWidget page

    Yep, the size constraint was the solution:

    Qt Code:
    1. //header for class holding tab widget
    2. QGridLayout* dataLayout;
    3. QWidget* page;
    4. QTabWidget* tabs;
    5. QVBoxLayout* mainLayout;
    6.  
    7. //constructor
    8. dataLayout = new QGridLayout();
    9. page = new QWidget(this);
    10. QScrollArea* scrollArea = new QScrollArea(this);
    11. dataLayout->setSizeConstraint(QLayout::SetFixedSize); //important!
    12. page->setLayout(dataLayout);
    13. scrollArea->setWidget(page);
    14. tabs->addTab(scrollArea, tr("Some items"));
    15. mainLayout->addWidget(tabs);
    16. this->setLayout(mainLayout);
    17.  
    18. //test add after construction
    19. for (int n = 0; n < 40; ++n)
    20. {
    21. SomeItem* item = new SomeItem(this);
    22. item->setStuff("whatever");
    23. dataLayout->addWidget(item);
    24. }
    To copy to clipboard, switch view to plain text mode 

    • Without setSizeConstraint(QLayout::SetFixedSize) the items will not even be displayed
    • Adding items in the constructor does not work (tried after every phase)
    • Not using a "page" QWidget and calling scrollArea->setLayout(dataLayout)
      does not work. Subclassing an actual custom Page widget from QWidget, however, is not
      required.


    I wonder what use does QScrollArea::setLayout() even have?

  7. #6
    Join Date
    Aug 2011
    Location
    Finland
    Posts
    18
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QScrollArea in a QTabWidget page

    I have discovered a refinement: setSizeConstraint(QLayout::SetFixedSize) stops the page widget from expanding in any direction when the entire tab widget is expanded, but these can be used instead.
    Qt Code:
    1. page->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
    2. scrollArea->setWidgetResizable(true);
    To copy to clipboard, switch view to plain text mode 
    Now the page widget will use all the space in can get, yet scroll bars will appear if that space is not enough.

Similar Threads

  1. how to detach Tab page from QTabWidget?
    By rajesh in forum Newbie
    Replies: 3
    Last Post: 30th May 2012, 17:20
  2. Scroll Buttons in page Area for QTAbwidget
    By vaibhav in forum Qt Programming
    Replies: 3
    Last Post: 26th August 2011, 15:59
  3. Replies: 4
    Last Post: 5th February 2010, 17:51
  4. Force focus to a QTabWidget page's widget
    By thomaspu in forum Qt Programming
    Replies: 1
    Last Post: 2nd January 2008, 07:54
  5. QTabWidget remove a page at the page's request
    By thomaspu in forum Qt Programming
    Replies: 2
    Last Post: 29th December 2007, 21:45

Tags for this Thread

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.