Как узнать вверх или вниз крутится колесико мыши в PyQt5 Python?

def wheelEvent(self, WheelEvent):
    delta = int(WheelEvent.pixelDelta().x())
    print(delta)

Постоянно выводится 0, хочу чтобы если крутилось вниз, то значение delta каждый раз уменьшалось, если вверх, то увеличивалось.


Ответы (1 шт):

Автор решения: S. Nick

QWheelEvent Class

Класс QWheelEvent содержит параметры, которые описывают событие колеса.

События колеса отправляются виджету под курсором мыши, но если этот виджет не обрабатывает событие, они отправляются виджету фокуса.

Есть два способа прочитать дельту события колеса:

  1. angleDelta() возвращает дельты в градусах колеса. Эти значения всегда предоставляются. angleDelta содержит угол поворота колеса.

  2. Функция pixelDelta() возвращает дельты в пикселях экрана и доступна на платформах с трекпадами высокого разрешения, таких как macOS. В этом случае source() вернет Qt::MouseEventSynthesizedBySystem.

    pixelDelta не является обязательным и может быть нулевым.

QPoint QWheelEvent::angleDelta() const

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

Положительное значение указывает, что колесо было повернуто вперед от пользователя;

отрицательное значение указывает, что колесо было повернуто назад к пользователю.

angleDelta().y() предоставляет угол, на который было повернуто общее вертикальное колесо мыши с момента предыдущего события.

angleDelta().x() предоставляет угол, на который было повернуто горизонтальное колесо мыши, если мышь имеет горизонтальное колесо; в противном случае он остается на нуле. Некоторые мыши позволяют пользователю наклонять колесо для горизонтальной прокрутки, а некоторые сенсорные панели поддерживают жест горизонтальной прокрутки; это также появится в angleDelta().x().

Большинство типов мыши работают с шагом 15 градусов, в этом случае значение дельты кратно 120;

то есть 120 единиц * 1/8 = 15 градусов.


from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog


class PhotoViewer(QtWidgets.QGraphicsView):
    photoClicked = QtCore.pyqtSignal(QtCore.QPoint)

    def __init__(self, parent):
        super(PhotoViewer, self).__init__(parent)
        self._zoom = 0
        self._empty = True
        self._scene = QtWidgets.QGraphicsScene(self)
        self._photo = QtWidgets.QGraphicsPixmapItem()
        self._scene.addItem(self._photo)
        self.setScene(self._scene)
        self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(30, 30, 30)))
        self.setFrameShape(QtWidgets.QFrame.NoFrame)

    def hasPhoto(self):
        return not self._empty

    def fitInView(self, scale=True):
        rect = QtCore.QRectF(self._photo.pixmap().rect())
        if not rect.isNull():
            self.setSceneRect(rect)
            if self.hasPhoto():
                unity = self.transform().mapRect(QtCore.QRectF(0, 0, 1, 1))
                self.scale(1 / unity.width(), 1 / unity.height())
                viewrect = self.viewport().rect()
                scenerect = self.transform().mapRect(rect)
                factor = min(viewrect.width()  / scenerect.width(),
                             viewrect.height() / scenerect.height())
                self.scale(factor, factor)
            self._zoom = 0

    def setPhoto(self, pixmap=None):
        self._zoom = 0
        if pixmap and not pixmap.isNull():
            self._empty = False
            self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
            self._photo.setPixmap(pixmap)
        else:
            self._empty = True
            self.setDragMode(QtWidgets.QGraphicsView.NoDrag)
            self._photo.setPixmap(QtGui.QPixmap())
        self.fitInView()

    def wheelEvent(self, event):
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
        print(f'event.angleDelta().y() -> {event.angleDelta().y()}')

        print(f'event.pixelDelta().isNull() -> {event.pixelDelta().isNull()}')
        print(f'event.pixelDelta()  x:y     -> {event.pixelDelta().x()}:{event.pixelDelta().y()}')
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        if self.hasPhoto():
            if event.angleDelta().y() > 0:
                factor = 1.25
                self._zoom += 1
            else:
                factor = 0.8
                self._zoom -= 1

            print(f'self._zoom -> {self._zoom}')
            if self._zoom > 0:
                self.scale(factor, factor)
            elif self._zoom == 0:
                self.fitInView()
            else:
                self._zoom = 0

    def toggleDragMode(self):
        if self.dragMode() == QtWidgets.QGraphicsView.ScrollHandDrag:
            self.setDragMode(QtWidgets.QGraphicsView.NoDrag)
        elif not self._photo.pixmap().isNull():
            self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)

    def mousePressEvent(self, event):
        if self._photo.isUnderMouse():
            self.photoClicked.emit(self.mapToScene(event.pos()).toPoint())
            rect_scene = self.mapToScene(self.viewport().rect())
            rect_item = self._photo.mapFromScene(rect_scene).boundingRect().toRect()
        super(PhotoViewer, self).mousePressEvent(event)


class Window(QtWidgets.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.viewer = PhotoViewer(self)

        # Кнопка `Загрузить изображение`
        self.btnLoad = QtWidgets.QToolButton(self)
        self.btnLoad.setText('Загрузить изображение')
        self.btnLoad.clicked.connect(self.loadImage)

        # Кнопка для перехода от перетаскивания к получению информации о пикселях
        self.btnPixInfo = QtWidgets.QToolButton(self)
        self.btnPixInfo.setText('Войдите в режим информации о пикселях')
        self.btnPixInfo.clicked.connect(self.pixInfo)
        self.editPixInfo = QtWidgets.QLineEdit(self)
        self.editPixInfo.setReadOnly(True)
        self.viewer.photoClicked.connect(self.photoClicked)

        # layout
        VBlayout = QtWidgets.QVBoxLayout(self)
        VBlayout.addWidget(self.viewer)
        HBlayout = QtWidgets.QHBoxLayout()
        HBlayout.setAlignment(QtCore.Qt.AlignLeft)
        HBlayout.addWidget(self.btnLoad)
        HBlayout.addWidget(self.btnPixInfo)
        HBlayout.addWidget(self.editPixInfo)
        VBlayout.addLayout(HBlayout)

    def loadImage(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(self,
                                                 "QFileDialog.getOpenFileName()", 
                                                 "",
                                                 "Image Files (*.png *.jpg *.jpeg *.bmp)",
                                                 options=options)
        if fileName:
            self.viewer.setPhoto(QtGui.QPixmap(fileName))

    def pixInfo(self):
        self.viewer.toggleDragMode()

    def photoClicked(self, pos):
        if self.viewer.dragMode()  == QtWidgets.QGraphicsView.NoDrag:
            self.editPixInfo.setText('%d, %d' % (pos.x(), pos.y()))


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 100, 800, 600)
    window.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка