views:

2321

answers:

6

I know that this is a very specific C++ and Qt related question, but maybe someone can help me, anyway ...

See the code below: I want to display an image within a scroll area. The view port of the scroll area shall have a defined initial size. That means, if the image's size is bigger than the initial size of the view port, scroll bars will be visible, otherwise not.

// create label for displaying an image
QImage image( ":/test.png" );
QLabel *label = new QLabel( this );
label->setPixmap( image.toPixmap() );

// put label into scroll area
QScollArea *area = new QScrollArea( this );
area->setWidget( label );

// set the initial size of the view port
// NOTE: This is what I'd like to do, but this method does not exist :(
area->setViewPortSize( QSize( 300, 300 ) );

It shall be possible to resize the whole application so that the view port will get another size than the initial one.

Unfortunatelly I was not able to find out, how to set the size of the view port. Qt's layout mechanism seems to set a default size for the view port, but up to now I was not able to change it. Setting a new size with

area->setMinimumSize( QSize( 300, 300 ) );

will actually set the demanded size, but then the scroll area looses the ability to get resized to a size smaller than 300x300.

Any ideas?

A: 

I don't think you can do exactly that very easily, which is (if I'm reading correctly), size the widget so that the internal area is 300x300. You might be able to fudge it, however, since a scroll area is a type of frame, which inherits from QWidget. This means you could just call area->resize( 300 + fudge, 300 + fudge ), where your fudge values account for the extra bit taken up by the frame's drawing.

I'm not sure this would work in a dynamically resizable dialog, however. I haven't ever done anything quite like this.

Caleb Huitt - cjhuitt
A: 

You can try:

class MyScrollArea : public QScrollArea
{
    virtual QSize sizeHint() const { return QSize( 300, 300 ); }
};

// create label for displaying an image
QImage image( ":/test.png" );
Label *label = new QLabel;
label->setPixmap( image.toPixmap() );

// put label into scroll area
QScollArea *area = new MyScrollArea( this );
area->setWidget( label );

However layout and Qt is amazingly Voodoo. It is IMO its least functional part.

if that doesn't work, try calling QWidget::resize() on various widgets.

Max Howell
+1  A: 

I think that you are looking at the problem the wrong way. The QScrollArea is just a widget that you put in a frame or QMainWindow. The size of the widget is controlled by the layout of the widget that contains it.

Take a look at this example from Trolltech: Image Viewer Example

Dusty Campbell
A: 

If you're trying to display an image inside a scroll area, your best bet isn't going with a label.

You should try using a QGraphicsView/QGraphicsScene/QGraphicPixmapItem (instead of the Scroll Area and label). The performance is far better when displaying images. The scroll area and label will re-draw the image very poorly as you move around using the scroll bars.

For example, you have a ".ui" file with a QGraphicsView on the gui called "qgvImageView" and a QImage called "image"...

QGraphicsScene *scene = new QGraphicsScene(qgvImageView);
QPixmap pixTmp(QPixmap::fromImage(image));
QGraphicsPixmapItem * ppixItem = scene->addPixmap( pixTmp );
ppixItem->setPos(0,0);

Check out the QT Documentation. BTW: This was introduced in Qt 4.2

I'm not sure if this will specifically fix the problem, but there is a chance that the QGraphicsView will react better to what you're trying to do.

Bob
A: 

Is the scroll area the top level widget? If so, simply call

area->resize(300,300);

If it's inside a hierarchy you need to resize the toplevel appropriately (complex), or set the minimumSize of the area. You could also try to experiment with the LayoutPolicy - assuming the sizeHint is QSize(300,300) you can give it the appropriate size policy according to what's defined in http://doc.trolltech.com/4.4/qsizepolicy.html#Policy-enum

Henrik Hartz
A: 

How about using

area->setGeometry(int x, int y, int w, int h);
Alpants