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 (or bottom) of the document. The vertical scroll bar is consuming the events before I can see them, and stops consuming them 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 area consumed them. This suffers the same problem whether installed on the preview widget itself or its internal QGraphicsView (found uding findChild()).
Both approaches shown below. Similar result Qt4.8.5 and 5.1.1 on Linux.
How do I get these events before the scroll area/bars?Cheers,
Chris@
#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:
void wheelEvent(QWheelEvent *event) {
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();
}
};class Widget : public QWidget {
Q_OBJECTpublic:
explicit Widget(QWidget parent = 0): QWidget(parent) {
m_printPreview = new PreviewWidget(this);
QVBoxLayout layout = new QVBoxLayout(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) {
QPainter p(printer);
QFont big("Arial", 200);
p.setFont(big);
for (int i = 0; i < 4; ++i) {
p.drawText(300, 200, QString::number(i));
printer->newPage();
}
}protected:
bool eventFilter(QObject *obj, QEvent *event) {
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[]) {
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"
@ -
Not sure if this'll help but I solved a similar problem using setFocus(), clearFocus(), setFocusPolicy() etc. You may be able to ask your QPrintPreviewWidget to let go of the events for a change and then catch those events with its parent or something, somehow :)
-
I have exactly the same problem and have not found an answer.
Someone please respond.
[edit] I solved it: I had the event handler in my mainwindow class. I have since moved it to my derived editwindow class:void CmpWin::wheelEvent(QWheelEvent *event) { if(event->modifiers() & Qt::ControlModifier) { int nDeg = event->delta(); if(nDeg > 0) setFontSize(0.0); else if(nDeg < 0) setFontSize(-1.0); event->accept(); } else QPlainTextEdit::wheelEvent(event); } // end wheelEvent()
setFontSize() is my own function to adjust the font my way. Replace with your own.
It works correctly now.