PDA

View Full Version : Issues writing a simple image viewer class



ultim8
26th March 2009, 20:34
Hey guys,

In the past I've used QLabel for displaying images. I am writing a image viewer class so that I can do more with the image I'm displaying. Long term goals including applying transformations to the image and even animating those transformations. But for a first step I just want to display an image.

I'm having issues with that however. If you look at the attached screenshot you'll see I've used my ImageViewer class to load an image of my dog, but it's only showing the top left portion of the image (you can just barely see his tail).

I have a feeling there is something wrong I'm doing with the minimumSizeHint and sizeHint functions, but I'm not sure.

I've attached the ImageViewer class along with a test program. I've also supplied the imageviewer.cpp inline below for quick reading.

Any help would be much appreciated!

#include "imageviewer.h"

#include <QPainter>
#include <QVBoxLayout>
#include <QScrollArea>
#include <QDebug>


ImageWidget::ImageWidget(QWidget *parent) : QWidget(parent)
{
}

ImageWidget::~ImageWidget()
{
}

void ImageWidget::setPixmap(const QPixmap &pixmap)
{
m_pixmap = pixmap;
update();
}

QSize ImageWidget::minimumSizeHint() const
{
// WHAT DO I PUT HERE???
if(!m_pixmap.isNull())
return m_pixmap.size();
else
return QWidget::sizeHint();
}

QSize ImageWidget::sizeHint() const
{
// AND HERE???
if(!m_pixmap.isNull())
return m_pixmap.size();
else
return QWidget::sizeHint();
}

void ImageWidget::paintEvent(QPaintEvent *event)
{
if(!m_pixmap.isNull())
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.save();
transformPainter(&painter);
drawPixmap(&painter);
painter.restore();
}
else
QWidget::paintEvent(event);
}

void ImageWidget::transformPainter(QPainter *painter)
{
// does nothing yet...
}

void ImageWidget::drawPixmap(QPainter *painter)
{
painter->drawPixmap(QPointF(0, 0), m_pixmap);
}


ImageViewer::ImageViewer(QWidget *parent/* = 0*/, Qt::WindowFlags f/* = 0*/) : QWidget(parent, f)
{
QVBoxLayout *baseLayout = new QVBoxLayout;
m_scrollArea = new QScrollArea(this);
m_imageWidget = new ImageWidget(m_scrollArea);
m_scrollArea->setWidget(m_imageWidget);
baseLayout->addWidget(m_scrollArea);

m_imageWidget->setMinimumSize(m_scrollArea->minimumSizeHint());

setLayout(baseLayout);
}

ImageViewer::~ImageViewer()
{
}

void ImageViewer::setPixmap(const QPixmap &pixmap)
{
m_imageWidget->setPixmap(pixmap);
}

aamer4yu
26th March 2009, 20:42
Your class is similar to QLabel...
Also search the forums before you post..

This thread (http://www.qtcentre.org/forum/f-qt-programming-2/t-how-to-browse-images-in-thumbnail-view-15739.html) is very much similar to yours...hope you get help from it...

ultim8
26th March 2009, 21:11
Your class is similar to QLabel...
Also search the forums before you post..

I know it's similar to QLabel. I stated in my initial post that I was trying to create an alternative to using QLabel.

I did search the forums, but I only found info on QGraphicsScene.... and as I understand it QGraphicsScene is for managing a large number of graphical items. It sounds like overkill for displaying a single image. (Please correct me if I'm wrong however).



This thread (http://www.qtcentre.org/forum/f-qt-programming-2/t-how-to-browse-images-in-thumbnail-view-15739.html) is very much similar to yours...hope you get help from it...
Again, references QGraphicsView/Scene. Seems to be overkill to display and do transformations on a single image.

Lykurg
26th March 2009, 22:07
Ok,

I don't have read all, but why do you want to do all the nasty work with the size thing by your own? Let Qt do the dirty work for you!

Since - I have said this this day already in an other post - QPixmap is a QPaintDevice use it! What I mean is:

store the given pixmap (gpm)
paint the gpm with transformations on a new pixmap (npm) you create
set this pixmap (npm) to the label

By doing so, you don't have to take care about all the layout stuff...


Lykurg

ultim8
26th March 2009, 23:20
Ok,

I don't have read all, but why do you want to do all the nasty work with the size thing by your own? Let Qt do the dirty work for you!

Since - I have said this this day already in an other post - QPixmap is a QPaintDevice use it! What I mean is:

store the given pixmap (gpm)
paint the gpm with transformations on a new pixmap (npm) you create
set this pixmap (npm) to the label

By doing so, you don't have to take care about all the layout stuff...
Lykurg

I've thought about that... but then I would have to store two copies of the image (one in my pixmap and one in the QLabel). Also I would have to copy the pixmap to the QLabel whenever I made a new transformation (I would imagine this would be an expensive operation if I were to animate my transformations).

By doing it in the method I'm attempting I don't have any of those issues. I store one pixmap... and I paint that one pixmap with the desired transformations onto the widget.

Instead of suggesting other options I would prefer some help with why my method is not working (unless people have suggestions that don't include QLabel ;))

ultim8
27th March 2009, 13:50
Turns out my issue was really trivial. When adding an image to a scroll area you need to call setWidgetResizable to true... otherwise the widget is never resized:

m_scrollArea->setWidgetResizable(true);

It now displays the image correctly (mostly that is... there are still some minor issues to resolve, but I think I can work those out).