Results 1 to 15 of 15

Thread: Issue with visuals when updating QGridLayout inside QScrollArea

  1. #1
    Join Date
    Jun 2011
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Issue with visuals when updating QGridLayout inside QScrollArea

    Hey guys, I have a QGridLayout inside a QFrame inside a QScrollArea. The QGridLayout holds lots of widgets.
    Each time a widget is added or removed, it runs this method:

    Notes:
    -TabBar is the main class; it is a QWidget
    -The updateLayout method is called whenever a tab is added or removed
    -tabLayoutScroller is a QScrollArea
    -tabLayout is a QGridLayout inside a QFrame. The QFrame is set as the main widget for tabLayoutScroller
    -tabs is a QList<QPushButton*>

    Qt Code:
    1. void TabBar::updateLayout()
    2. {
    3. tabLayoutScroller->setUpdatesEnabled(false);
    4.  
    5. for(int i = 0; i < tabLayout->columnCount(); i++)
    6. {
    7. if(!(tabLayout->itemAtPosition(0, i)))
    8. break;
    9. tabLayout->itemAtPosition(0, i)->widget()->hide();
    10. tabLayout->itemAtPosition(0, i)->widget()->deleteLater();
    11. delete tabLayout->itemAtPosition(0, i);
    12. }
    13.  
    14. QLayoutItem *child;
    15. while ((child = tabLayout->takeAt(0)) != 0)
    16. delete child;
    17.  
    18. tabLayout->invalidate();
    19.  
    20. for(int i = 0; i < tabs.count(); i++)
    21. tabLayout->addWidget(tabs.at(i), 0, tabLayout->columnCount());
    22.  
    23. tabLayoutScroller->setUpdatesEnabled(true);
    24.  
    25. tabLayoutScroller->update();
    26. tabLayoutScroller->repaint();
    27. }
    To copy to clipboard, switch view to plain text mode 

    The problem is, if I have lots of widgets open, and I close lots of them, then open lots of them... the visuals glitch out quite a bit. See:
    http://i.imgur.com/oer5q.png

    This is an odd problem that I have yet to figure out. Any help is highly appreciated; thanks all.
    Last edited by TimeBomb; 17th June 2011 at 09:39.

  2. #2
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Thanks
    1
    Thanked 26 Times in 26 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    It seems to me like some widgets are left behind and they are not deleted. Try to check for memory leaks.

    Also calling update() and repaint() does nothing when you use setUpdatesEnabled (false).
    Last edited by Rachol; 17th June 2011 at 08:59.

  3. #3
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    Have a look at inline comments

    Qt Code:
    1. void TabBar::updateLayout()
    2. {
    3. tabLayoutScroller->setUpdatesEnabled(false);
    4.  
    5. QLayoutItem *child;
    6. while ((child = tabLayout->takeAt(0)) != 0)
    7. delete child;
    8.  
    9. tabLayoutScroller->update(); //Redundant, Consider Removing
    10. tabLayoutScroller->repaint(); //Redundant, Consider Removing
    11.  
    12. tabLayout->invalidate (); //try adding this, usually not required
    13.  
    14. for(int i = 0; i < tabs.count(); i++)
    15. tabLayout->addWidget(tabs.at(i), 0, tabLayout->columnCount());
    16.  
    17. tabLayoutScroller->update(); //Redundant, Consider Removing
    18. tabLayoutScroller->repaint(); //Redundant, Consider Removing
    19.  
    20. tabLayoutScroller->setUpdatesEnabled(true);
    21. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by Santosh Reddy; 17th June 2011 at 15:00. Reason: updated contents

  4. #4
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Thanks
    1
    Thanked 26 Times in 26 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    Quote Originally Posted by Santosh Reddy View Post
    Have a look at inline comments

    Qt Code:
    1. QLayoutItem *child;
    2. while ((child = tabLayout->takeAt(0)) != 0) // This does not seem to a good way, because the item returned may not always be your widget
    3. delete child; // it may also be some layout internally added spacer, for layout adjustment
    To copy to clipboard, switch view to plain text mode 
    Since the point of this code is to remove everything from the layout, I don't see a problem here. According to the documentation that is the recommended way of clearing the layout. Take a look at QLayoutItem * QLayout::takeAt ( int index ) method description.

  5. #5
    Join Date
    Jun 2011
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    Hey guys; thanks a lot for the tips. Frustratingly, my problem still occurs. I have updated my original post in this thread with the latest code I am using. I have done my best to make sure everything is deleted, and there are no leaks or whatnot.

    As always, any help is highly appreciated. Thanks again all!

  6. #6
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Thanks
    1
    Thanked 26 Times in 26 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    How do you handle the content of tabs.at(i)?

  7. #7
    Join Date
    Jun 2011
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    Quote Originally Posted by Rachol View Post
    How do you handle the content of tabs.at(i)?
    When you add or remove a tab, it modifies the tabs object. Then, the tabs object is loaded in to the QGridLayout via the updateLayout method.

    The base of the method that adds a tab:
    Qt Code:
    1. TabButton *button = new TabButton(this, tab);
    2. button->setMouseTracking(true);
    3. button->resize(24, 24);
    4. button->setMaximumSize(24, 24);
    5. button->setStyleSheet(stylesheetDefault);
    6. connect(button, SIGNAL(pressed()), SLOT(changeTab()));
    7. tabs.insert(index, button);
    8. updateLayout();
    To copy to clipboard, switch view to plain text mode 

    The base of the method that removes a tab:
    Qt Code:
    1. TabButton *button = tabs.at(index);
    2.  
    3. tabs.removeAt(index);
    4.  
    5. updateLayout();
    To copy to clipboard, switch view to plain text mode 


    ..Do you think it may be a better idea to just add or remove a single widget from the QGridLayout (instead of removing them all and then adding them all back in each time a tab is added/removed)?

  8. #8
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    Quote Originally Posted by Rachol
    Since the point of this code is to remove everything from the layout, I don't see a problem here. According to the documentation that is the recommended way of clearing the layout. Take a look at QLayoutItem * QLayout::takeAt ( int index ) method description.
    You are right, I just was reading it as itemAt() instead of takeAt()


    Added after 26 minutes:


    Try this..

    Qt Code:
    1. void TabBar::updateLayout()
    2. {
    3. tabLayoutScroller->setUpdatesEnabled(false);
    4.  
    5. // remove tabs
    6. for(int i = 0; i < tabs.count(); i++)
    7. tabLayout->removeWidget(tabs.at(i));
    8.  
    9. // add tabs
    10. for(int i = 0; i < tabs.count(); i++)
    11. tabLayout->addWidget(tabs.at(i), 0, tabLayout->columnCount());
    12.  
    13. tabLayoutScroller->setUpdatesEnabled(true);
    14. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by Santosh Reddy; 17th June 2011 at 15:18.

  9. #9
    Join Date
    Jun 2011
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    @Santosh Reddy:
    The tabs I may be removing may no longer be in the tabs QList. That is why I remove everything in the layout, not just from the tabs QList.


    I have modified my code a bit so it only adds/takes one at a time. I can't edit my previous posts now for whatever odd reason, so here is the new code:
    Qt Code:
    1. void TabBar::updateLayout(int index, TabButton *tab)
    2. {
    3.  
    4. tabLayoutScroller->setUpdatesEnabled(false);
    5.  
    6. if (index == -1)
    7. tabLayout->removeWidget(tab);
    8. else {
    9. tabLayout->addWidget(tab, 0, index);
    10. }
    11.  
    12. tabLayoutScroller->setUpdatesEnabled(true);
    13.  
    14. tabLayoutScroller->update();
    15. tabLayoutScroller->repaint();
    16. }
    To copy to clipboard, switch view to plain text mode 

    Code for adding a tab:
    Qt Code:
    1. TabButton *button = new TabButton(this, tab);
    2. button->setMouseTracking(true);
    3. connect(button, SIGNAL(pressed()), SLOT(changeTab()));
    4. updateLayout(index, button);
    5. tabs.insert(index, button);
    To copy to clipboard, switch view to plain text mode 

    Code for removing a tab:
    Qt Code:
    1. TabButton *button = tabs.at(index);
    2.  
    3. updateLayout(-1, tabs.at(index));
    4.  
    5. tabs.removeAt(index);
    To copy to clipboard, switch view to plain text mode 

    The original visual glitch still occurs though, even when it is removing/adding so simplistically =/. As always, any help is highly appreciated; thanks.

  10. #10
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Thanks
    1
    Thanked 26 Times in 26 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    Hi,

    I took a little time and have written a short program that in my opinion represent what I think you are trying to achieve.

    There is a MainWidget which contains QScrollArea and QPushButton("Add"). QScrollArea contains a TabBar(QFrame) on which I have set QHBoxLayout. Clicking "Add" button will add a new TabButton(QPushButton) into the TabBar. Clicking TabButton will remove it.

    Please take a look at it, it might help you to find the solution, or then you can guide me more based on what I have written, so I can maybe reproduce your problem.

    --Rachol
    Attached Files Attached Files

  11. #11
    Join Date
    Jun 2011
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    Quote Originally Posted by Rachol View Post
    Hi,

    I took a little time and have written a short program that in my opinion represent what I think you are trying to achieve.

    There is a MainWidget which contains QScrollArea and QPushButton("Add"). QScrollArea contains a TabBar(QFrame) on which I have set QHBoxLayout. Clicking "Add" button will add a new TabButton(QPushButton) into the TabBar. Clicking TabButton will remove it.

    Please take a look at it, it might help you to find the solution, or then you can guide me more based on what I have written, so I can maybe reproduce your problem.

    --Rachol
    Hi Rachol; thanks a lot for all your help.
    Changing from QGridLayout to QHBoxLayout seemed to speed up some things a tad.

    But the problem still occurred.
    After some moderate testing, I have deduced that this problem occurs because each button has a QIcon. When all the buttons never have QIcons, this 'visual glitch' never occurs. The QIcon is the website's favicon, and it is one of the main ways to identify one tab from another (the project that is around this tab system is a web browser).

    I have tried using the setIcon method to set the current icon to an empty QIcon() right before removing the button from the QList<button> as well as from the QHBoxLayout, but the visual glitch still occurs.

    Once again, any help is appreciated. Thanks a lot all.

  12. #12
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Thanks
    1
    Thanked 26 Times in 26 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    I tried to play with Icons, I couldn't get any visual problem. How is your TabButton implemented?

  13. #13
    Join Date
    Jun 2011
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    Hi. In the attached zip, you will find 4 files.
    Please note that this tab layout, in case I have not already explained, is used in a web browser application.
    tabs.cpp and tabs.h
    This includes the following classes:
    TabPreviewer - A QLabel designed to display a QPixmap(The website rendered and resized), as well as the website title.
    TabButton - The QPushButton that is the base tab
    TabMenu - This can be ignored. It is a QListWidget that is designed to essentially show a list of all the tabs upon a button being clicked.
    TabBar - This is where most of the guts occurs. It is the QWidget containing all the visual stuff.
    Tabs - This is the QStackedWidget. Each widget in here is a "Tab" object, and inside that "Tab" object is a QWebView(well, a derived version of QWebView [BrowserView]). The only reason you should need to look through this is if you want to see how variables in TabBar/TabButton interact with it.

    And then there is tab.cpp and tab.h:
    This is just the Tab class. A Tab is a QWidget containing a BrowserView[derived from QWebView].

    At some point soon, I will more than likely seperate each class in to it's own file.

    I apologize for the messiness of my code. If there is something you can not understand or have questions about, feel free to ask me.

    I thought it would be best to send you this instead of going back and forth between everything, as the problem may or may not be in something I have not talked about much yet.

    Thanks a lot for your help, it is really appreciated.



    UPDATE: Issue is fixed. Someone on IRC told me that removeAt/removeWidget just removes the item from the list/layout - it doesn't delete the item. In the TabBar::removeAt method, I remove the TabButton, and then (I didn't do this before) I delete the actual TabButton object. This seems to solve all my problems.
    Thanks a lot to everyone who helped.
    Attached Files Attached Files
    Last edited by TimeBomb; 18th June 2011 at 10:23.

  14. #14
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Thanks
    1
    Thanked 26 Times in 26 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    I was just going to write that...

  15. #15
    Join Date
    Jun 2011
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Issue with visuals when updating QGridLayout inside QScrollArea

    Quote Originally Posted by Rachol View Post
    I was just going to write that...
    Hehe. Nonetheless, thanks a lot for baring with me, I appreciate the help.
    This issue was blocking the release of the next alpha version of my app, so I am glad it is fixed.

Similar Threads

  1. getting to the buttons inside a QGridLayout
    By mr_kazoodle in forum Newbie
    Replies: 2
    Last Post: 19th February 2011, 16:48
  2. Replies: 2
    Last Post: 29th October 2010, 09:44
  3. Resizing QGraphicsView inside a QGridLayout
    By mckinnon in forum Newbie
    Replies: 3
    Last Post: 9th September 2010, 10:15
  4. QGridLayout issue
    By talk2amulya in forum Qt Programming
    Replies: 3
    Last Post: 2nd January 2010, 18:32
  5. Problem with QScrollArea updating from 4.0.1 to 4.1.0
    By SkripT in forum Qt Programming
    Replies: 8
    Last Post: 28th January 2006, 22:35

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.