def eventFilter(self, source, event): modifier = QGuiApplication.queryKeyboardModifiers() if event.type() == QEvent.MouseMove: # emit mouse moved signal and the drag signal if the mouse # button is clicked position = event.pos() self.mouse_moved.emit(position) if self.is_clicked: self.dragged.emit(position) return False if event.type() == QEvent.Wheel: # emit the mouse moved signal when the mousewheel is used position = event.pos() self.mouse_moved.emit(position) if event.type() == QEvent.MouseButtonPress \ or event.type() == QEvent.MouseButtonDblClick: # set the mouse button clicked state and emit the clicked signal # if neither control nor alt modifiers are pressed if not modifier == Qt.ControlModifier\ and not modifier == Qt.AltModifier: self.is_clicked = True position = event.pos() self.clicked.emit(position) return False if event.type() == QEvent.MouseButtonRelease: # release the mouse button clicked state and emit the release # signal if neither ctontrol nor alt modifiers are pressed. self.is_clicked = False if not modifier == Qt.ControlModifier\ and not modifier == Qt.AltModifier: position = event.pos() self.released.emit(position) return False if event.type() == QEvent.Leave: # emit a leave signal self.leave.emit() return False return False
def eventFilter(self, obj, event): if obj == self.child_obj and event.type() == QEvent.Wheel: self.do_wheel(event) return True elif obj == self.child_obj and event.type() == QEvent.MouseButtonPress: self.start_mouse_pos = event.localPos() self.start_scroll_pos = self.page().scrollPosition() return QWebEngineView.eventFilter(self, obj, event) # Make scrollbar work normally elif obj == self.child_obj and event.type() == QEvent.MouseMove: # Only process mouse move with left button pressed if event.buttons() != Qt.LeftButton: return QWebEngineView.eventFilter(self, obj, event) # If Ctrl is pressed, use the default event handler. This enable select text. if QGuiApplication.queryKeyboardModifiers() == Qt.ControlModifier: return QWebEngineView.eventFilter(self, obj, event) ''' OK. This is a mouse drag without Ctrl pressed. We will change it's behavior to something like ImageView. ''' current_mouse_pos = event.localPos() delta = current_mouse_pos - self.start_mouse_pos ''' Note: if mouse moves down 5 pixels, it's y-pos increase 5 pixels. The page should also move down 5 pixels which means the scrollbar should move up 5 pixels and the scroll position should decrease. ''' target_scroll_pos = self.start_scroll_pos - delta ''' Verify value range. I don't know if this is a must or whether this has any effects or not. ''' target_scroll_x = target_scroll_pos.x() target_scroll_y = target_scroll_pos.y() if target_scroll_x < 0: target_scroll_x = 0 if target_scroll_y < 0: target_scroll_y = 0 if target_scroll_x > self.page().contentsSize().width(): target_scroll_x = self.page().contentsSize().width() if target_scroll_y > self.page().contentsSize().height(): target_scroll_y = self.page().contentsSize().height() ''' We notice that if the page is zoomed in, the scrollbar moves faster than the mouse cursor. Besides, the scrollbar may jump a large distance towards the end in a weird way if you place the mouse cursor at the right bottom corner and try to drag the page towards the left upper corner several times. I don't know why but I print the target_scroll_pos which seems indeed correct. So I guess this may be caused by the scrollTo function in JavaScript. I think this function doesn't do things as I thought it would. Now that the page scrolls faster than mouse cursor dragging only after the page is zoomed in and it seems they have multiples relation, I guess if I divide the target_scroll_pos by zoomFactor, the page scrolling speed may be slow down and maybe scrollTo can scroll the page to correct position. Finally, this way is indeed the solution. However, I don't know why. If the page is zoomed out, it would be the opposite. The page scrolling speed should be sped up to match the mouse cursor. ''' target_scroll_x /= self.zoomFactor() target_scroll_y /= self.zoomFactor() # https://forum.qt.io/topic/60091/scroll-a-qwebengineview/3 self.page().runJavaScript(f"window.scrollTo({target_scroll_x}, {target_scroll_y})") return QWebEngineView.eventFilter(self, obj, event) # Make scrollbar work normally elif obj == self.child_obj and event.type() == QEvent.MouseButtonDblClick and event.buttons() == Qt.RightButton: self.setZoomFactor(1) return True return QWebEngineView.eventFilter(self, obj, event)