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

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

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

pyqt5

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

1 Ответ

0 голосов
/ 09 января 2019

Вы стоите 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_())
...