Reputation: 38631
Consider this example:
#!/usr/bin/env python
import sys,os
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import Qt
class MainWindow(QtWidgets.QMainWindow):
class ScrollAreaWheel(QtWidgets.QScrollArea): # SO:9475772
def __init__(self, parent=None):
super(MainWindow.ScrollAreaWheel, self).__init__(parent)
self.parent = parent
def wheelEvent(self, event):
print("wheelEvent", event.angleDelta().y())
def __init__(self):
#~ self.do_init = QtCore.QEvent.registerEventType()
QtWidgets.QMainWindow.__init__(self)
self.setMinimumWidth(1000)
self.setMinimumHeight(400)
self.frame1 = QtWidgets.QFrame(self)
self.frame1.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame1layout = QtWidgets.QGridLayout(self.frame1)
self.frame1layout.setSpacing(0);
self.frame1layout.setContentsMargins(0,0,0,0);
self.frame1widget = QtWidgets.QWidget()
self.frame1widget.setLayout(QtWidgets.QGridLayout())
self.frame1layout.addWidget(self.frame1widget)
self.frame1scroll = MainWindow.ScrollAreaWheel(self) #QtWidgets.QScrollArea()
self.frame1scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.frame1scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.frame1widget.layout().addWidget(self.frame1scroll, 0, 0) #, Qt.AlignCenter)
#self.frame1scrolllayout = QtWidgets.QHBoxLayout(self.frame1scroll)
self.frame1scrolllayout = QtWidgets.QGridLayout(self.frame1scroll)
self.frame1scroll.setWidget(self.frame1scrolllayout.widget())
self.frame1scroll.setWidgetResizable(True)
self.frame1scroll.setAlignment(Qt.AlignCenter)
self.frame1label = QtWidgets.QLabel()
self.frame1scrolllayout.addWidget(self.frame1label, 0, 0, Qt.AlignCenter) ##
pixmap = QtGui.QPixmap(200, 100)
pixmap.fill(Qt.red)
self.frame1label.setPixmap(pixmap)
self.frame2 = QtWidgets.QFrame(self)
self.frame2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame2layout = QtWidgets.QHBoxLayout(self.frame2)
self.frame2layout.setSpacing(0);
self.frame2layout.setContentsMargins(0,0,0,0);
self.frame2scroll = QtWidgets.QScrollArea(self)
self.frame2scroll.setWidgetResizable(True)
self.frame2widget = QtWidgets.QWidget()
self.frame2widget.setLayout(QtWidgets.QGridLayout())
self.frame2scroll.setWidget(self.frame2widget)
self.frame2layout.addWidget(self.frame2scroll)
self.mainwid = QtWidgets.QWidget()
self.mainwid.setLayout(QtWidgets.QGridLayout())
self.setCentralWidget(self.mainwid)
self.splitter1 = QtWidgets.QSplitter(Qt.Horizontal)
self.splitter1.addWidget(self.frame1)
self.splitter1.addWidget(self.frame2)
self.splitter1.setSizes([600, 600]); # equal splitter at start
self.mainwid.layout().addWidget(self.splitter1)
self.mainwid.layout().update()
if __name__ == "__main__":
app = QtWidgets.QApplication([])
main = MainWindow()
main.show()
sys.exit(app.exec_())
It generates this (Ubuntu 18.04):
I want to use mousewheel only on the left QScrollArea, for which I've made a separate class. However, its wheelEvent fires only when I'm outside the red box, not when I hover over it. How can I make ScrollAreaWheel.wheelEvent fire even when mouse is over the child label (the red box)?
Upvotes: 1
Views: 70
Reputation: 244132
You are the QLabel
placing on top of the QScrollArea
instead of placing it inside, visually it is the same but at the level of events it is not.
from PyQt5 import QtCore, QtGui, QtWidgets
class ScrollAreaWheel(QtWidgets.QScrollArea):
def wheelEvent(self, event):
print("wheelEvent", event.angleDelta().y())
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setMinimumSize(1000, 400)
frame1 = QtWidgets.QFrame(frameShape=QtWidgets.QFrame.StyledPanel)
scrollarea1 = ScrollAreaWheel(widgetResizable=True)
scrollarea1.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
scrollarea1.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
widget1 = QtWidgets.QWidget()
scrollarea1.setWidget(widget1)
label_lay = QtWidgets.QGridLayout(widget1)
lay1 = QtWidgets.QVBoxLayout(frame1)
lay1.addWidget(scrollarea1)
pixmap = QtGui.QPixmap(200, 100)
pixmap.fill(QtCore.Qt.red)
label = QtWidgets.QLabel(pixmap=pixmap)
label_lay.addWidget(label, 0, 0, QtCore.Qt.AlignCenter)
#==============================
frame2 = QtWidgets.QFrame(frameShape=QtWidgets.QFrame.StyledPanel)
scrollarea2 = QtWidgets.QScrollArea(widgetResizable=True)
scrollarea2.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
scrollarea2.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
widget2 = QtWidgets.QWidget()
scrollarea2.setWidget(widget2)
splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
splitter.addWidget(frame1)
splitter.addWidget(frame2)
splitter.setSizes([600, 600])
self.setCentralWidget(splitter)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
Upvotes: 1