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_OBJECT

    public:
    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 :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.