daisy
daisy

Reputation: 23501

Catch the signal when QWebView was scrolled to the end

When a user scroll with his mouse within a QWebView widget , can i know if he got to the head / end of web contents ?

I may place a QWebView::wheelEvent() inside , but how can i know about the scroll positions ?

Thanks !

Upvotes: 0

Views: 955

Answers (2)

The Compiler
The Compiler

Reputation: 11939

I found this question when searching for an actual signal when the scroll position was changed.

There is the QWebPage::scrollRequested signal which can be used. The documentation says This signal is emitted whenever the content given by rectToScroll needs to be scrolled dx and dy downwards and no view was set., however the last part is wrong, the signal is actually always emitted.

I contributed a fix for this to Qt, so this will probably be corrected as soon as the docs are updated.


(original post following)

QWebView doesn't provide this because WebKit manages the scroll-area.

I ended up extending paintEvent to check the scroll position there, and emit a signal when it has changed.

PyQt code which emits a scroll_pos_changed signal with a percentage:

class WebView(QWebView):

    scroll_pos_changed = pyqtSignal(int, int)

    def __init__(self, parent=None):
        super().__init__(parent)
        self._scroll_pos = (-1, -1)

    def paintEvent(self, e):
        """Extend paintEvent to emit a signal if the scroll position changed.

        This is a bit of a hack: We listen to repaint requests here, in the
        hope a repaint will always be requested when scrolling, and if the
        scroll position actually changed, we emit a signal..
        """
        frame = self.page_.mainFrame()
        new_pos = (frame.scrollBarValue(Qt.Horizontal),
                   frame.scrollBarValue(Qt.Vertical))
        if self._scroll_pos != new_pos:
            self._scroll_pos = new_pos
            m = (frame.scrollBarMaximum(Qt.Horizontal),
                 frame.scrollBarMaximum(Qt.Vertical))
            perc = (round(100 * new_pos[0] / m[0]) if m[0] != 0 else 0,
                    round(100 * new_pos[1] / m[1]) if m[1] != 0 else 0)
            self.scroll_pos_changed.emit(*perc)
        # Let superclass handle the event
        return super().paintEvent(e)

Upvotes: 0

pnezis
pnezis

Reputation: 12321

You can check the scrollPosition of the page's mainframe:

QPoint currentPosition = webView->page()->mainFrame()->scrollPosition();

if (currentPosition.y() == webView->page()->mainFrame()->scrollBarMinimum(Qt::Vertical))
   qDebug() << "Head of contents";
if (currentPosition.y() == webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical))
   qDebug() << "End of contents";

Upvotes: 1

Related Questions