PDA

View Full Version : dynamic qscrollarea



hijinks
25th September 2006, 21:06
I have a freeflow layout inside a scrollarea that when new labels get added to that freeflow layout the scrollarea does not work. The scrollbar never changes even if I resize the form.

Here is some code



#include <QtGui>

#include "flowlayout.h"
#include "window.h"
#include "dropsitewidget.h"

Window::Window()
{

// setting up the debig textbox
this->log = new QTextEdit;


// setting up the flow layout
this->flowLayout = new FlowLayout;
this->flowLayout->setSizeConstraint(QLayout::SetMinimumSize);

QScrollArea *scrollArea = new QScrollArea;
scrollArea->setLayout(this->flowLayout);

// adding the 20 labels for images
for (int i=0; i<20; i++) {
//this->flowLayout->addWidget(new QLabel(tr("its a label")));

QLabel *label = new QLabel("image here");
label->setFixedSize(100,100);

this->labelList.append(label);
this->flowLayout->addWidget(this->labelList.at(i));
}

// adding the widget to do the drag and drop
dropSiteWidget = new DropSiteWidget;
connect(dropSiteWidget, SIGNAL(sendLog(QString)), log, SLOT(append(QString)));
connect(dropSiteWidget, SIGNAL(sendImage(QString)), this, SLOT(newImage(QString)));



QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(dropSiteWidget);
layout->addWidget(scrollArea);
layout->addWidget(log);
setLayout(layout);

this->count = 0;

setWindowTitle(tr("Flow Layout"));
}

void Window::newImage(QString str) {
// loading the new image
QPixmap *img = new QPixmap(str);

// checking if its a valid image
if (!img->isNull()) {
// scaling the image now
QPixmap smallImg;
smallImg = img->scaledToWidth(100);

this->labelList.at(this->count)->setPixmap(smallImg);
this->count++;
}
}



freeflow and dragdropwidget are taken from the examples

jpn
26th September 2006, 06:05
Try using QScrollArea::setWidget() instead of this:


scrollArea->setLayout(this->flowLayout);

Just wrap the flow layout in a widget and set it into the scroll area by using the method mentioned above.

hijinks
26th September 2006, 14:29
I have tried that too.. but the widget does not scale.. i guess i'd need to subclass it to scale correctly?

jpn
26th September 2006, 17:48
Ok, I see the problem. A scroll area does not resize it's widget by default. Therefore a wrapper widget (containing the flow layout) inside the scroll area can have as much space as it wants and the labels don't get laid like you want. You can make the QScrollArea to resize it's widget by setting QScrollArea::widgetResizable property as true. This is not enough for a proper solution, though. This way the labels would get laid correctly, but no scroll bars appear before there is less available space than a one single label requires. This is because FlowLayout::sizeHint() returns only the size of the biggest label. So clearly the FlowLayout needs some patching.. ;)

At first, you need a wrapper widget as we were discussing earlier. You could set the scroll area up more or less like this:


QScrollArea* scroll = new QScrollArea(this);
QWidget* wrapper = new QWidget(scroll);
FlowLayout* flow = new FlowLayout(wrapper);
for (int i = 0; i < 20; ++i)
{
QLabel* label = new QLabel("image here", wrapper);
label->setFixedSize(100, 100);
flow->addWidget(label);
}
wrapper->setLayout(flow);
scroll->setWidget(wrapper);
scroll->setWidgetResizable(true);


Then, you'll need to modify the FlowLayout to get the desirable behaviour. Make FlowLayout::minimumSize() look like this:


QSize FlowLayout::minimumSize() const
{
int w = geometry().width();
int h = doLayout(QRect(0, 0, w, 0), true);
return QSize(w, h);
}