QPrintPreviewWidget mouse wheel events
G'day all,
Perhaps I am suffering brain fade or caffeine withdrawal but I am sure someone can help.
I have a QPrintPreviewWidget displaying a multi-page document. The mouse wheel scrolls up and down through the pages quite happily. I'd like to trap mouse wheel events when the Control key is pressed to zoom in and out.
My first approach was to subclass QPrintPreviewWidget and override wheelEvent(). Unfortunately the new wheelEvent() does not get called unless the preview scroll area has moved all the way to the top (bottom) of the document. The vertical scroll bar is consuming the event before I can see it, and stop consuming it if it can no longer scroll. The result is the Ctrl-Wheel only zooms at top or bottom of the document.
My second approach was to install an event filter hoping to see the wheel events before the scroll bars consumed them. This suffers the same problem.
Both approaches shown below. Similar result Qt4.8.4 and 5.1.0 on Linux.
How do I get these events before the scroll area/bars?
Cheers,
Chris
Code:
#include <QApplication>
#include <QDebug>
#include <QPainter>
#include <QPrinter>
#include <QPrintPreviewWidget>
#include <QVBoxLayout>
#include <QWheelEvent>
#include <QWidget>
#include <cmath>
class PreviewWidget: public QPrintPreviewWidget {
Q_OBJECT
public:
PreviewWidget
(QWidget *parent
= 0): QPrintPreviewWidget
(parent
) { }
protected:
if (event->orientation() == Qt::Vertical && (event->modifiers() & Qt::ControlModifier)) {
double numDegrees = event->delta() / 8.0;
double numSteps = numDegrees / 15.0;
double factor = std::pow(1.125, numSteps);
zoomIn(factor);
event->accept();
}
event->ignore();
}
};
Q_OBJECT
public:
m_printPreview = new PreviewWidget(this);
layout->addWidget(m_printPreview);
connect(m_printPreview,
SIGNAL(paintRequested
(QPrinter*)),
SLOT(paintRequested
(QPrinter*)));
setLayout(layout);
resize(400, 800);
// m_printPreview->installEventFilter(this);
}
public slots:
void paintRequested
(QPrinter *printer
) { p.setFont(big);
for (int i = 0; i < 4; ++i) {
p.
drawText(300,
200,
QString::number(i
));
printer->newPage();
}
}
protected:
if (obj
== m_printPreview
&& event
->type
() == QEvent::Wheel) { QWheelEvent *wheelEvent
= static_cast<QWheelEvent
*>
(event
);
if (wheelEvent->orientation() == Qt::Vertical && (wheelEvent->modifiers() & Qt::ControlModifier)) {
double numDegrees = wheelEvent->delta() / 8.0;
double numSteps = numDegrees / 15.0;
double factor = std::pow(1.125, numSteps);
m_printPreview->zoomIn(factor);
// wheelEvent->accept();
return true;
}
// wheelEvent->ignore();
return false;
}
else {
// standard event processing
return QObject::eventFilter(obj, event
);
}
}
private:
PreviewWidget *m_printPreview;
};
int main(int argc, char *argv[]) {
Widget w;
w.show();
return a.exec();
}
#include "main.moc"
Re: QPrintPreviewWidget mouse wheel events
You can always install event filter on qApp and filter the event out only if m_printPreview is underMouse().
Re: QPrintPreviewWidget mouse wheel events
It's a bit like using a sledgehammer to crack a walnut though :)
Re: QPrintPreviewWidget mouse wheel events
Looks like it is the sledgehammer approach or nothing. The scroll bars belong to a private QGraphicsView and the events are not routed via QPrintPreviewWidget in any way I can see.
On the plus side, I solved another problem by "accident" while looking at this one. :D