QScrollArea -- Scroll to widget problem
Hi,
I have a scrollarea that contains buttons. When I add a button to the area and immediately call ensureWidgetVisible for that button, the scrollarea does not moves to the widget however, if I call ensureWidgetVisible from another button it works. Seem to me that it something related to call this function immediately after adding a button.
Here is a code the mimics the error:
main.cpp
Code:
#include <QtGui>
int main(int argc, char *argv[])
{
window.resize(320, 240);
QWidget *scrollAreaWidgetContents_2;
scrollArea
->setGeometry
(QRect(1,
1,
231,
61));
scrollArea->setWidgetResizable(true);
scrollAreaWidgetContents_2
= new QWidget();
scrollAreaWidgetContents_2
->setGeometry
(QRect(0,
0,
238,
36));
verticalLayout
= new QVBoxLayout(scrollAreaWidgetContents_2
);
verticalLayout->addLayout(horizontalLayout_2);
scrollArea->setWidget(scrollAreaWidgetContents_2);
window.show(); //Will not work
QList<QPushButton *> buttons;
buttons.
append(new QPushButton("Button 1",scrollAreaWidgetContents_2
));
buttons.
append(new QPushButton("Button 2",scrollAreaWidgetContents_2
));
buttons.
append(new QPushButton("Button 3",scrollAreaWidgetContents_2
));
buttons.
append(new QPushButton("Button 4",scrollAreaWidgetContents_2
));
buttons.
append(new QPushButton("Button 5",scrollAreaWidgetContents_2
));
int pos;
for (pos = 0; pos<=buttons.count()-1;pos++)
{
buttons
[pos
]->setGeometry
(QRect(80,
330,
112,
26));
}
for (pos = 0; pos<=buttons.count()-1;pos++)
{
horizontalLayout_2->addWidget(buttons[pos]);
}
//window.show(); //Will work
scrollArea->ensureWidgetVisible(buttons[3],0,0);
return a.exec();
}
In this example the ensureWidgetVisible fuction will work depending on where I have the show function.
Any ideas what I am missing? Some refresh before calling ensureWidgetVisible?
Many thanks.
Re: QScrollArea -- Scroll to widget problem
First - I recommend to read QScrollArea::setWidget. There are some dependencies according to order in which objects are added.
After show() there are some changes and recreation of QScrollArea internal layouts. After that - he can says where selected widgets are and move to that position.
So - create enitre internal widget and then add it as main widget for scrollarea.
Re: QScrollArea -- Scroll to widget problem
To create the entire internal widget beforehand will work in the given example however, it it will not work for example: if a user clicks on a "Add new" button to add a new element to the scrollview because this changes internal layouts. For example:
Add_new_clicked()
Code:
buttons.
append(new QPushButton("New button",scrollAreaWidgetContents_2
));
buttons
[buttons.
count()-1]->setGeometry
(QRect(80,
330,
112,
26));
horizontalLayout_2->addWidget(buttons[buttons.count()-1]); //Add the new element and it is show in the screen
//How to move to this new element?
scrollArea->ensureWidgetVisible(buttons[buttons.count()-1],0,0); //This does not work.
Re: QScrollArea -- Scroll to widget problem --Solved
I'm replying to my post.
Indeed this happens because the scroll area's widget changes it geometry with every button that is added. Thus, ensureWidgetVisible cannot be called immediately because the scroll area does not know its final size yet. A way around is to subclass a QWidget and emit a signal after the widget size changes (by reimplementing the resizeEvent) + setting this widget as the scroll areas's widget. After connecting the signal, ensureWidgetVisible can properly scroll to the added widget.
Re: QScrollArea -- Scroll to widget problem
Hello :) I had the same problem and managed to fix it quite easy: Call qApp->processEvents(); before calling the ensureWidgetVisible() method.
The idea is that when the geometry changes, events for doing that are pushed on the event queue... So you execute the events to make the geometry changes and then you can ensure the widget is visible. Of course, these things are happening in the UI thread...
I hope this helps someone out there. Cheers!