PDA

View Full Version : Simple Image Grid Approach?



bibbinator
4th April 2011, 05:17
Hi,
I'm not exactly new to Qt, but I'm stumped on how to display a grid of images the way I want.

* Each image is 128 x 128 pixels

* Images are displayed in a resizable area (splitter and/or window size changes the area)

* The images should be displayed in a grid at a fixed size. E.g. as the user changes the area it will fit as many whole image columns as it can without stretching, extending rows as necessary. So at 256 wide it would show 2 columns, at 300 wide it would still show 2 columns until it hits 384, etc.

* A vertical scrollbar should appear when the area cannot contain all the images.

I have tried using QGridLayout with each image shown as a QWidget but it stretches my images and won't automatically put images on another when too narrow. I also tried a QListWidget but the icon size seems to be fixed at a small size and I couldn't get it to display the full 128 pixel image.

Can somebody point me in the right direction?

Thanks :-)

Brett

tbscope
4th April 2011, 05:25
A QScrollArea?

Why do you want scrollbars and not show the pictures when they can not be shown fully?
I mean, isn't it easier to apply a grid layout in a scroll area and be done?

bibbinator
4th April 2011, 05:44
Hi tbscope,
Thanks for your note.

I'm not sure I get you, but I think it's what I'm trying to do mostly. As the user narrows the view and images disappear, instead of a scrollbar appearing I want to rearrange the window to show columns that fit on the screen and extend the rows if needed. The problem I had was that the QGridLayout kept stretching my image widgets.

Can this be achieved with just scroll area?

ChiliPalmer
4th April 2011, 12:15
No, the Qt Layouts aren't dynamic and the images won't be rearranged automatically. You will have to do that yourself.
I'm working on pretty much the same and my idea was to use a QScrollArea with horizontalScrollBarPolicy set to Qt::ScrollBarAlwaysOff and reimplement the resizeEvent to have the widget containing the images reorder them.
It might be more efficient to store your images in the QPixmapCache and in the resizeEvent just call update() on the viewport widget. This widget then would have to calculate where to put each image in it's paintEvent

JohannesMunk
4th April 2011, 12:16
I think what you are looking for is a flowlayout inside a scroll area.

http://doc.trolltech.com/latest/layouts-flowlayout.html (http://doc.trolltech.com/latest/layouts-flowlayout.html)

HIH

Johannes

ChiliPalmer
4th April 2011, 12:48
That looks just right. If you use a flowlayout all you would have to do ist to resize the widget with the flowlayout in the QScrollAreas resizeEvent

bibbinator
4th April 2011, 14:24
Thanks guys,

Johannes that is exactly what I was looking for. I don't know how I missed that demo. I looked at all of them but somehow the use of the buttons threw me off and I skipped that one. Doh.

Cheers

bibbinator
6th April 2011, 14:16
I have tried everything but can't seem to get scrollbars to appear when using flowlayout. As an easy test case, I'm trying to modify the flowlayout demo to show scrollbars when you resize the window smaller than content area.

I saw in the scrollarea doc


If a scroll area is used to display the contents of a widget that contains child widgets arranged in a layout, it is important to realize that the size policy of the layout will also determine the size of the widget. This is especially useful to know if you intend to dynamically change the contents of the layout. In such cases, setting the layout's size constraint property to one which provides constraints on the minimum and/or maximum size of the layout (e.g., QLayout::SetMinAndMaxSize) will cause the size of the scroll area to be updated whenever the contents of the layout changes.

I commented out the old layout linking directly to the parent window, and added code to put up scrollbars. Can anybody see anything wrong with this code?

EDIT: Forgot to say the problem - The window won't resize smaller than all the controls.



Window::Window()
{
FlowLayout *flowLayout = new FlowLayout;

flowLayout->addWidget(new QPushButton(tr("Short")));
flowLayout->addWidget(new QPushButton(tr("Longer")));
flowLayout->addWidget(new QPushButton(tr("Different text")));
flowLayout->addWidget(new QPushButton(tr("More text")));
flowLayout->addWidget(new QPushButton(tr("Even longer button text")));

// setLayout(flowLayout);

QWidget *scrollWidget = new QWidget();
scrollWidget->setLayout(flowLayout);
QScrollArea *scrollArea = new QScrollArea();
scrollArea->setWidget(scrollWidget);
flowLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);

QHBoxLayout *centralLayout = new QHBoxLayout();
centralLayout->addWidget(scrollWidget);
this->setLayout(centralLayout);

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

JohannesMunk
6th April 2011, 14:43
Hi!

Two things:

1) You probably meant: centralLayout->addWidget(scrollArea); Because as of right now you are not actually showing your scrollarea.

2) You have to enable: scrollArea->setWidgetResizable(true);

HIH

Joh

bibbinator
6th April 2011, 15:07
Hi Joh,
Thanks for following up.

You're right, I mistyped and centralLayout->addWidget(scrollArea) made it work, doh! I didn't need to set the widget to resizable for some reason.

I'll now back port this into my project and hopefully all will be well.

Thanks again!

Added after 4 minutes:

In case somebody else finds this thread, note that you do also need setWidgetResizable(true) as Joh suggested otherwise the layout container stops working (but the scrollbar appears okay).

JohannesMunk
6th April 2011, 15:23
Yes, exactly. The flowlayout will otherwise not be "notified"/resized from the scrollarea, if you resize it. So the layout stays at its original size and appears to be nonfunctional.

Joh