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();
}
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();
}