Pyqt Wheel event
Asked Answered
B

1

7

I implemented an image browser where I use the wheel event of the mouse to show the next image. The problem is, if the user scrolls too fast, the position value of the scroll wheel jumps over and swallows the values in between. Does anybody know how I can overcome this problem? If I scroll slowly, I get a decreasing value (-1, -2, -3); if I scroll fast I get something like (-1, -5, -6, -11). The problem appears on WindowsXP & 7.

Here is a sample code.

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys

#############Define MyWindow Class Here ############
class MyWindow(QMainWindow):
##-----------------------------------------
  def __init__(self):
    QMainWindow.__init__(self)
    self.label = QLabel("No data")
    self.label.setGeometry(100, 200, 100, 100)
    self.setCentralWidget(self.label)
    self.setWindowTitle("QMainWindow WheelEvent")
    self.x = 0
##-----------------------------------------
  def wheelEvent(self,event):
    self.x =self.x + event.delta()/120
    print self.x
    self.label.setText("Total Steps: "+QString.number(self.x))
##-----------------------------------------
##########End of Class Definition ##################


def main():
  app = QApplication(sys.argv)
  window = MyWindow()
  window.show()
  return app.exec_()

if __name__ == '__main__':
 main()
Byelostok answered 21/11, 2013 at 14:43 Comment(2)
What kind of mouse are you using? Is the wheel "clicky" or "smooth"? Does the value of event.delta() remain constant? My mouse wheel is "clicky", and the delta is a constant ±120 units.Pardew
Mine is kind of smooth and the value does not stay constant. If I scroll fast its goes in 120er steps, e.g. 120,120,240,360.Byelostok
P
10

There does not appear to be any problem here, as Qt is correctly reporting the number of units scrolled by the mouse wheel.

Some mouse drivers support accelerated scrolling, which means that the number of reported scroll units is progressively increased when the wheel is rotated more rapidly. The units are 0.125 of a degree, and most mice have a baseline scroll speed of 120 units per "notch". Acceleration simply multiplies the baseline speed by an increasing factor as the wheel is rotated faster (i.e. 120, 240, 360, etc).

So in a QWheelEvent, the number of "notches" scrolled is calculated by:

    # PyQt5/PySide2
    event.angleDelta().y() // baseline_speed

    # PyQt4/PySide
    event.delta() // baseline_speed 

which is exactly what the example code in the question already does.

if you want to regsiter each "notch/step" separately, you could just use a loop:

    steps = event.angleDelta().y() // 120
    vector = steps and steps // abs(steps) # 0, 1, or -1
    for step in range(1, abs(steps) + 1):
        self.x += vector
        print(self.x)

Or you could ignore the acceleration, and just register the vector for each wheel event:

    delta = event.angleDelta().y()
    self.x += (delta and delta // abs(delta))
    print(self.x)
Pardew answered 22/11, 2013 at 19:18 Comment(1)
basically still true, even if event.delta() was deprecated and we have pixelDelta() or angleDelta() now.Kicker

© 2022 - 2024 — McMap. All rights reserved.