PDA

View Full Version : QScrollarea events transferring to scrollbar



babu198649
27th November 2007, 10:41
hi
i have subclassed QScrollArea to receive mouse move events .
now when i move the mouse the scrollbars should be moved accordingly(up and down movements for vertical scrollbar and left and right movements for horizontal scrollbar).

how can i transfer the mouse move event of scrollarea to scrollbar

wysota
27th November 2007, 11:29
i have subclassed QScrollArea to receive mouse move events .
now when i move the mouse the scrollbars should be moved accordingly(up and down movements for vertical scrollbar and left and right movements for horizontal scrollbar).

how can i transfer the mouse move event of scrollarea to scrollbar

Why not use QScrollBar::setValue() to set the value of the scrollbar?

babu198649
27th November 2007, 11:50
yes i have tried it but it makes exection slower.

i have tried like this


void iv_scrollarea::mouseMoveEvent ( QMouseEvent * event )
{
if(this->underMouse())
{
if(old_position.x() > event->pos().x())//old position is qpoint it remembers last position
this->horizontalScrollBar()->setValue(this->horizontalScrollBar()->value() + 1);

if(old_position.x() < event->pos().x())
this->horizontalScrollBar()->setValue(this->horizontalScrollBar()->value() - 1);

if(old_position.y() > event->pos().y())
this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() + 1);

if(old_position.y() < event->pos().y())
this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() - 1);
}
old_position = event->pos();
}

the above code takes long movement of the mouse to move the label inside the QScrollArea. because at every pixel moved the movement of label does not happen

and when i set values with higher than setValue(1) (i.e. this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() - 5))

the flickering occurs:confused:


when i use the move() function of label inside scrollarea mouse move event it works fine but scrollbars are not updated

wysota
27th November 2007, 11:55
Ok, what effect are you trying to achieve anyway? Why do you add "1" instead of computing the actual movement?

babu198649
27th November 2007, 12:01
Ok, what effect are you trying to achieve anyway?

i want to move the qlabel inside the qscrollarea using mouse cursor (i.e. click and move the label) simultaneously the scrollbars should get updated.

wysota
27th November 2007, 12:35
Doesn't something like this work?

#include <QScrollArea>
#include <QLabel>
#include <QApplication>

class ScrollArea : public QScrollArea {
public:
ScrollArea(const QString &path) : QScrollArea(0){
QLabel *l = new QLabel(this);
setWidget(l);
setWidgetResizable(true);
l->setPixmap(QPixmap(path));
}
};


int main(int argc, char **argv){
QApplication app(argc, argv);
ScrollArea sa(argv[1]);
sa.show();
return app.exec();
}

The scrolling works for me out of the box.

babu198649
27th November 2007, 13:22
the problem is not with scrolling
when i move the qlabel with the mouse(clicked and move ) the label moves a distance with respect to the distance moved by the mouse .now the scrollbar should update this movement of the label.



QLabel *l = new QLabel(this);
setWidget(l);


is this keyword nessary

jpn
27th November 2007, 13:24
Why don't you use built-in components, QMdiArea or QGraphicsView (depending on your needs) as already suggested in another thread (http://www.qtcentre.org/forum/f-qt-programming-2/t-qscrollarea-slider-problem-10332.html)?

babu198649
27th November 2007, 13:32
hi
i have found in the documentation that the QGraphicsView is for maintaining large number of items . but i have only one label so i thought it will not suit.

and QMdiArea class documentation says

The QMdiArea widget provides an area in which MDI windows are displayed.

but i dont have more than one window and also i need time to know what MDI windows are . so i thought that i can do these things with qscrollarea itself.

do u think the problem can not be solved with QScrollarea

wysota
27th November 2007, 13:32
You should really use QMdiArea or QGraphicsView as suggested, but if you insist on using the scroll area directly then this works for me:

#include <QScrollArea>
#include <QLabel>
#include <QApplication>
#include <QMouseEvent>
#include <QScrollBar>


class ScrollArea : public QScrollArea {
public:
ScrollArea(const QString &path) : QScrollArea(0){
l = new QLabel(this);
setWidget(l);
setWidgetResizable(true);
l->setPixmap(QPixmap(path));
l->installEventFilter(this);
}
bool eventFilter(QObject *o, QEvent *e){
if(o!=l)
return QScrollArea::eventFilter(o,e);
if(e->type()==QEvent::MouseButtonPress){
m_prev = ((QMouseEvent*)e)->pos();
return true;
}
if(e->type()==QEvent::MouseMove){
QPoint pt = ((QMouseEvent*)e)->pos();
QPoint diff = pt-m_prev;
m_prev = pt;
horizontalScrollBar()->setValue(horizontalScrollBar()->value()+diff.x());
verticalScrollBar()->setValue(verticalScrollBar()->value()+diff.y());
return true;
}
return QScrollArea::eventFilter(o,e);
}
protected:
QLabel *l;
QPoint m_prev;
};


int main(int argc, char **argv){
QApplication app(argc, argv);
ScrollArea sa(argv[1]);
sa.show();
return app.exec();
}

babu198649
27th November 2007, 14:01
Thank u very much wysota
it really works great .
thanks for pain taking job of coding entirely :o in a short perid for me

wysota
27th November 2007, 14:39
You would have saved me the pain if you used the right component for the job in the first place.

babu198649
27th November 2007, 14:52
yes
but i followed the image viewer example

wysota
27th November 2007, 15:03
I advise you to follow JPN's hints next time. Your use case seemed a perfect candidate for QGraphicsView, especially if you intend to do something more with it (like introduce zooming).

babu198649
29th November 2007, 08:30
sure, thank u

Sirganor
6th September 2013, 23:33
You should really use QMdiArea or QGraphicsView as suggested, but if you insist on using the scroll area directly then this works for me:

#include <QScrollArea>
#include <QLabel>
#include <QApplication>
#include <QMouseEvent>
#include <QScrollBar>


class ScrollArea : public QScrollArea {
public:
ScrollArea(const QString &path) : QScrollArea(0){
l = new QLabel(this);
setWidget(l);
setWidgetResizable(true);
l->setPixmap(QPixmap(path));
l->installEventFilter(this);
}
bool eventFilter(QObject *o, QEvent *e){
if(o!=l)
return QScrollArea::eventFilter(o,e);
if(e->type()==QEvent::MouseButtonPress){
m_prev = ((QMouseEvent*)e)->pos();
return true;
}
if(e->type()==QEvent::MouseMove){
QPoint pt = ((QMouseEvent*)e)->pos();
QPoint diff = pt-m_prev;
m_prev = pt;
horizontalScrollBar()->setValue(horizontalScrollBar()->value()+diff.x());
verticalScrollBar()->setValue(verticalScrollBar()->value()+diff.y());
return true;
}
return QScrollArea::eventFilter(o,e);
}
protected:
QLabel *l;
QPoint m_prev;
};


int main(int argc, char **argv){
QApplication app(argc, argv);
ScrollArea sa(argv[1]);
sa.show();
return app.exec();
}

It makes something wrong when you drag it more than one pixel in one direction. Is accumulative. I got one solution for it:


#include <QScrollArea>
#include <QLabel>
#include <QApplication>
#include <QMouseEvent>
#include <QScrollBar>
#include<QDebug>

class ScrollArea : public QScrollArea {
public:
ScrollArea() : QScrollArea()
{
this->n=3;
this->prev_diff.setX(0);
this->prev_diff.setY(0);
l = new QLabel(this);
QImage imagen("C:/donostia.jpg");
l->setPixmap(QPixmap::fromImage(imagen));
setWidget(l);
setWidgetResizable(true);
//l->setPixmap(QPixmap(path));
l->installEventFilter(this);
}
bool eventFilter(QObject *o, QEvent *e)
{
if(o!=l)
return QScrollArea::eventFilter(o,e);
if(e->type()==QEvent::MouseButtonPress)
{
m_prev = ((QMouseEvent*)e)->pos();
this->prev_diff.setX(0);
this->prev_diff.setY(0);
return true;
}
if(e->type()==QEvent::MouseMove)
{
QPoint pt = ((QMouseEvent*)e)->pos();
this->diff = pt-m_prev-prev_diff*n;
m_prev = pt;
horizontalScrollBar()->setValue(horizontalScrollBar()->value()+diff.x()*n);
verticalScrollBar()->setValue(verticalScrollBar()->value()+diff.y()*n);
qDebug()<<"("+QString::number(diff.x())+","+QString::number(diff.y())+")";
this->prev_diff=diff;
return true;
}
return QScrollArea::eventFilter(o,e);
}
protected:
QLabel *l;
QPoint m_prev;
QPoint diff;
QPoint prev_diff;
int n;
};


int main(int argc, char **argv)
{
QApplication app(argc, argv);
ScrollArea sa;
sa.show();
return app.exec();
}