PDA

View Full Version : Speed up adding widgets with setUpdatesEnabled



niko
10th July 2006, 19:58
I have a QScrollArea with a lot of QLineEdits in it. The Problem is that it takes about 2sec on my computer to add 20 new QLineEdits, Take a look at this test-window:


TestWidget::TestWidget(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout* mainLayout = new QHBoxLayout;
setLayout(mainLayout);

QPushButton* testButton = new QPushButton("add");
connect(testButton, SIGNAL(clicked()), this, SLOT(addButtons()));
mainLayout->addWidget(testButton);

QWidget* textWidget = new QWidget;

QScrollArea* scrollArea = new QScrollArea;
scrollArea->setWidget(textWidget);
mainLayout->addWidget(scrollArea);
scrollArea->setWidgetResizable(true);

layout = new QHBoxLayout;
textWidget->setLayout(layout);
}
void TestWidget::addButtons() {
setUpdatesEnabled(false); //doesn't help
for(int i=0;i<20;i++) {
QLineEdit* lineEdit = new QLineEdit("foo");
layout->addWidget(lineEdit);
}
setUpdatesEnabled(true);
}


...i found setUpdatesEnabled but that one doesn't have any effect. What to do else?
Or how could I improve this else?

niko

Ben.Hines
10th July 2006, 21:14
I'm not 100% sure on this, but I think adding the controls to the scroll view causes update events to be queued up on the event queue. These updates don't actually take place until the control returns to the event loop. I.e. AFTER your TestWidget constructor returns. Therefore, the setUpdatesEnabled calls within the addButtons() method (called from the contstructor) will have no effect.

One thing you could try is to replace the call to setUpdatesEnabled(true) with a call to QTimer::singleShot(0, this, SLOT(mySlotThatReenablesUpdates())). This timer event should go onto the event queue AFTER the update events caused by adding the buttons.

You'll want to add the slot TestWidget::mySlotThatReenablesUpdates() that simply calls setUpdatesEnabled(true);

Let me know if this helps.

niko
11th July 2006, 18:40
thanks for your reply, but it doesn't help :(

my new code:


TestWidget::TestWidget(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout* mainLayout = new QHBoxLayout;
setLayout(mainLayout);

QPushButton* testButton = new QPushButton("add");
connect(testButton, SIGNAL(clicked()), this, SLOT(addButtons()));
mainLayout->addWidget(testButton);

QWidget* textWidget = new QWidget;

QScrollArea* scrollArea = new QScrollArea;
scrollArea->setWidget(textWidget);
mainLayout->addWidget(scrollArea);
scrollArea->setWidgetResizable(true);

layout = new QHBoxLayout;
textWidget->setLayout(layout);
}
void TestWidget::addButtons() {
setUpdatesEnabled(false);
for(int i=0;i<20;i++) {
QLineEdit* lineEdit = new QLineEdit("foo");
layout->addWidget(lineEdit);
}
QTimer::singleShot(0, this, SLOT(enableUpdates()));
}
void TestWidget::enableUpdates() {
setUpdatesEnabled(true);
}



....what alternatives do i have - using a QScrollBar instead of a QScrollArea and doing the scrolling myselve? (sounds quite hard to me :D - does have some example code on this?)

niko

aMan
11th July 2006, 18:56
have you tried to add the 20 QLineEdits to a normal widget?

maybe the scrollarea has a bug or something..

regards, aman..

niko
11th July 2006, 19:32
tried that allready, doesn't make much difference...

aMan
11th July 2006, 21:33
i've tried adding 50 lineedits to a scrollarea (i took some code from your post) and it's fast enough. i'm on a 800mhz machine..

so the problem is probably in another place..

i've appended my prog. but beware, it's not realy nice written..

regards, aman..

niko
12th July 2006, 19:10
on my machine it takes about 2sec, after having 200 added it takes about 3sec.
is it faster for you?

I'm on Gentoo Linux 2.6.16, Xorg 7.0, nvidia-drivers - other Qt(3) apps have normal speed.

aMan
12th July 2006, 19:22
strange..

i'm on
suse 10.1
kernel: 2.6.16.13-4
xorg 6.9.0 -> edit: and an intel gma 9xx with the intel drivers..
qt 4.1.0

edit:
@1733 mhz adding 200 takes about 2 seconds..
@800 mhz 4seconds..

regards..
aman..

jpn
12th July 2006, 21:51
It is advised to create widgets with an appropriate parent, so the layout doesn't have to do the re-parenting. Check this thread (http://www.qtcentre.org/forum/f-qt-programming-2/t-qt4-layout-of-complex-dialog-is-very-slow-1257.html#12).
Another considerable thing could be to disable the whole layout during adding a bunch of widgets and then re-enabling afterwards.


An enabled layout adjusts dynamically to changes; a disabled layout acts as if it did not exist.


Is this any smoothier?

niko
14th July 2006, 15:51
thanks for that tip, the testcase is now much faster.

however it didn't help much in my actual widget :(

see here what i'm trying to do:
http://www.qtcentre.org/forum/f-newbie-4/t-use-qscrollarea-qlistview-or-qscrollbar-2960.html

thanks!
niko