[Qt-interest] Bad performance: RubberBand on scaled Pictures using The Graphics View Framework
Tobias Omernik
tobi at asinteg.de
Thu Mar 25 11:41:56 CET 2010
I'm working on a simple PictureViewer using the Graphics View Framework
as it offers quite nice benefits.
However, I want to have a zoom-function by selecting a part of the image
with the RubberBand, but there is a very
disturbing effect when the image is scaled: bad Performance. The
RubberBand lurches and doesn't move fluently on scaled images.
This ONLY happens on scaled images.
I tried several methods to fix the problem for example:
- using the RubberBandDrag-Mode of the QGraphicsView [this one got
another Problem: it leaves a trail of lines behind it]
- using the QRubberBand widget triggered by events (as it is shown in
the documentation)
Here is a very basic example-code to show the problem:
(this is the method using the RubberBandDrag-Mode because this is the
simplest and smallest method)
#include <QtGui/QApplication>
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene *pScene = new QGraphicsScene;
QGraphicsPixmapItem *pPic = new QGraphicsPixmapItem;
QGraphicsView *pView = new QGraphicsView(pScene);
QPixmap pm("./Pic2.jpeg");
pPic->setPixmap(pm);
pScene->addItem(pPic);
pView->setDragMode(QGraphicsView::RubberBandDrag);
pView->scale(0.5,0.5); //doesnt matter if you scale the View or
the Pixmapitem
pView->show();
return a.exec();
}
The only way to come along with this problem is to use the QRubberBand
widget and DON'T pass a parent to QRubberBand's constructor. As the
documentation says: "If no parent is passed, QRubberBand will act as a
top-level widget". In this case it moves fluently but also can leave the
QGraphicScene, even the whole mainwindow and is visible on the complete
screen.
Additional an examplecode of this version:
main.cpp :
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h :
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <QtGui>
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
bool eventFilter(QObject *obj, QEvent *event);
private:
QGraphicsScene *pScene;
QGraphicsPixmapItem *pPic;
QGraphicsView *pLook;
QRubberBand *pRubber;
QPoint origin;
bool b_rubactive;
};
#endif // MAINWINDOW_H
mainwindow.cpp :
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QWidget(parent),
pScene(0),
pPic(0),
pLook(0),
pRubber(0)
{
b_rubactive = false;
pScene = new QGraphicsScene;
pPic = new QGraphicsPixmapItem;
pLook = new QGraphicsView(pScene);
pRubber = new QRubberBand(QRubberBand::Rectangle); //<-- no parent
is passed
QPixmap pm("./Pic2.jpeg"); //<--- insert a picture-path here
pPic->setPixmap(pm);
pScene->addItem(pPic);
pScene->installEventFilter(this);
pLook->scale(0.5,0.5);
QGridLayout *box = new QGridLayout(this);
box->addWidget(pLook,0,0);
this->setLayout(box);
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event) //using an
Eventfilter is NOT the Problem
{
if (obj == pScene)
{
QGraphicsSceneMouseEvent *mouseEvent =
static_cast<QGraphicsSceneMouseEvent*>(event);
if (event->type() == QEvent::GraphicsSceneMousePress)
{
origin = mouseEvent->screenPos();
pRubber->setGeometry(QRect(origin, QSize()));
pRubber->show();
b_rubactive = true;
return true;
}
else if (event->type() == QEvent::GraphicsSceneMouseMove)
{
if (b_rubactive)
pRubber->setGeometry(QRect(origin,
mouseEvent->screenPos()).normalized());
return true;
}
else if (event->type() == QEvent::GraphicsSceneMouseRelease)
{
b_rubactive = false;
pRubber->hide();
return true;
}
else {return false;}
}
else
{
// pass the event on to the parent class
return QWidget::eventFilter(obj, event);
}
}
MainWindow::~MainWindow()
{
}
I'm developing under Linux (openSuse 11.2). Hope you can tell me more
about this problem and/or give me a solution.
Tobi
More information about the Qt-interest-old
mailing list