PDA

View Full Version : QGraphicsView scrolling problem with 4.3.0



hb
28th June 2007, 16:05
To work around the bug described in this post (http://www.qtcentre.org/forum/f-qt-programming-2/t-calling-qthreadexec-repeatedly-7746.html), I installed Qt 4.3.0 now. The bug seems fixed indeed, however, I am now experiencing another problem that was not present with Qt 4.2.3.

I derived a class from QGraphicsView, and did a custom implementation for scrolling when the user clicks on the background. That implementation worked flawlessly with Qt 4.2.3, but in Qt 4.3.0, it only works if I set at least one of the scrollbar policies not to ...AlwaysOff.

I attached a minimal self-containing compilable example below. I'd have said it's a bug introduced in 4.3.0, but in contrast to the original code, that example doesn't work as expected even if compiled against 4.2.3...

I am puzzled. Any help would be greatly appreciated.



#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsTextItem>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QScrollBar>

class MyWidget : public QGraphicsView
{
public:
MyWidget(QGraphicsScene *scene, QWidget *parent = 0);

protected:
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);

private:
void storeMouseEvent(QMouseEvent *event);
bool scrolling;
QMouseEvent lastMouseEvent;
};

MyWidget::MyWidget(QGraphicsScene *scene, QWidget *parent)
: QGraphicsView(scene, parent), scrolling(false),
lastMouseEvent(QEvent::None,QPoint(),Qt::NoButton, Qt::NoButton,Qt::NoModifier)
{
// If at least one of these has the policy ..AlwaysOn, scrolling works
// (in both directions)!
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOf f);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff) ;
}

void MyWidget::storeMouseEvent(QMouseEvent *event)
{
lastMouseEvent = QMouseEvent(event->type(), event->pos(),
event->globalPos(),
event->button(),event->buttons(),event->modifiers());
}

void MyWidget::mousePressEvent(QMouseEvent *event)
{
// just handle left button presses on the background
QGraphicsItem *item = itemAt(event->pos());

if(!item) {
if((event->button() == Qt::LeftButton)) {
scrolling = true;
storeMouseEvent(event);
event->accept();
return;
}
}
event->ignore();
QGraphicsView::mousePressEvent(event);
}

void MyWidget::mouseMoveEvent(QMouseEvent *event)
{
// perform scrolling if scrolling is active
if(scrolling) {
QPoint delta = event->globalPos() - lastMouseEvent.globalPos();
QScrollBar *hBar = horizontalScrollBar();
QScrollBar *vBar = verticalScrollBar();
hBar->setValue(hBar->value() + (isRightToLeft() ? delta.x() : -delta.x()));
vBar->setValue(vBar->value() - delta.y());
storeMouseEvent(event);
event->accept();
return;
}
event->ignore();
QGraphicsView::mouseMoveEvent(event);
}

void MyWidget::mouseReleaseEvent(QMouseEvent *event)
{
// end scrolling mode if it was active
if((event->button() == Qt::LeftButton) && (scrolling == true)) {
scrolling = false;
storeMouseEvent(event);
event->accept();
return;
}
event->ignore();
QGraphicsView::mouseReleaseEvent(event);
}

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QGraphicsScene scene;
MyWidget widget(&scene);
QGraphicsTextItem item("hello");
scene.addItem(&item);
widget.show();
scene.setSceneRect(-1000,-1000,2000,2000);
return app.exec();
}

spud
28th June 2007, 16:18
Hi,
I reported this problem to the Qt Task tracker some time ago. It got the issue nr #167439 but I can't seem to find it anymore. Anyway the trolls answered:



Thank you for your bug-report.

> QGraphicsView ScrollBarPolicy behaviour changed with Qt 4.3
>
> What I did:
> Created a QGraphicsView and I set both scrollbarPolicies to
> ScrollBarAlwaysOff and the DragMode to ScrollHandDrag.
>
> What I expected to see:
> Up until Qt 4.2 I could use the hand or mouse wheel to scroll.

Happy days anyway. This bug is fixed in the latest snapshot, and will be
a part of the 4.3.1 release.

jpn
28th June 2007, 16:26
Try QAbstractScrollArea::scrollContentsBy():


scrollContentsBy((isRightToLeft() ? -delta.x() : delta.x()), delta.y());

hb
28th June 2007, 17:08
Thanks spud. I'll wait for 4.3.1 to come out then, hoping that it will indeed fix this problem.

hb
28th June 2007, 17:10
Try QAbstractScrollArea::scrollContentsBy():


I was thinking about that function as well, but this quote from the docs made me not use it:


Calling this function in order to scroll programmatically is an error, use the scroll bars instead (e.g. by calling QScrollBar::setValue() directly).

jpn
28th June 2007, 17:14
I was thinking about that function as well, but this quote from the docs made me not use it:
Good notice. :) Anyway, I'm not exactly sure if it really causes any problems in this case since scroll bar policies are set to Qt::ScrollBarAlwaysOff. One would have to explore the sources a bit to find out..

hb
28th June 2007, 17:22
Good notice. :) Anyway, I'm not exactly sure if it really causes any problems in this case since scroll bar policies are set to Qt::ScrollBarAlwaysOff. One would have to explore the sources a bit to find out..

True, but I'd rather not go for that. Even if it works in this version, you can never know about future versions if that use-case is so directly discouraged in the docs. Thanks anyways :)

Elgot
30th August 2007, 16:01
Thanks spud. I'll wait for 4.3.1 to come out then, hoping that it will indeed fix this problem.

Is it just me, or is this broken in 4.3.1 too?

Bitto
30th August 2007, 23:18
Hm... the regression with scrollbars was fixed in 4.3.1, and there were no outstanding QGV bugs at the time 4.3.1 was released.