Реагирует ли QScrollArea на wheelEvent, в том числе в космосе, занятом детьми?

1

Рассмотрим этот пример:

#!/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_())

Он генерирует это (Ubuntu 18.04):

Изображение 174551

Я хочу использовать колесико мыши только слева QScrollArea, для которого я создал отдельный класс. Однако его wheelEvent срабатывает только тогда, когда я нахожусь вне красной рамки, а не когда я нахожу над ним. Как я могу запустить ScrollAreaWheel.wheelEvent, даже если мышь находится над дочерней меткой (красная рамка)?

Теги:
pyqt5
pyqt
qscrollarea

1 ответ

1
Лучший ответ

Вы размещаете QLabel поверх QScrollArea вместо того, чтобы помещать его внутрь, визуально это то же самое, но на уровне событий это не так.

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_())

Ещё вопросы

Сообщество Overcoder
Наверх
Меню