Results 1 to 8 of 8

Thread: PyQt: zooming with QGraphicsSceneWheelEvent

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Feb 2017
    Posts
    6
    Qt products
    Qt5
    Platforms
    Unix/X11

    Question PyQt: zooming with QGraphicsSceneWheelEvent

    I am new to both (Py)Qt and Python. I am currently trying to write my first PyQt app in the form of a simple image viewer I have dubbed shufti. So far I have got it to load images files from the command line and... well that's about all so far. Now I want to be able to zoom in and out of the shufti QGraphicsView window by scrolling the mousewheel over the window but I'm having trouble figuring out how that should work.

    What I have been able to deduce is that I should be able to achieve this using QGraphicsSceneWheelEvent / QGraphicsSceneWheelEvent.delta and then I'd need to hook that up to adjust the self.view.scale() object within the initUI method, somehow.

    I've had a search but I've not been able to find any examples of people using QGraphicsSceneWheelEvent / WheelEvent with PyQt so I'm hoping someone could explain how I might get the two interacting?

    Thanks


    Qt Code:
    1. #!/usr/bin/python3
    2. # -*- coding: utf-8 -*-
    3. #
    4. # shufti - A WIP, PyQt5 persistent image viewer
    5. #
    6. # By Dan MacDonald
    7. #
    8. # 2017
    9. #
    10. # Usage:
    11. #
    12. # python shufti.py path/to/image
    13.  
    14. import sys
    15. from PyQt5 import QtCore
    16. from PyQt5.QtGui import QPixmap
    17. from PyQt5.QtWidgets import QMainWindow, QApplication, QGraphicsScene, QGraphicsView
    18.  
    19. class Shufti(QMainWindow):
    20.  
    21. def __init__(self):
    22. super().__init__()
    23. try:
    24. self.file = open(sys.argv[1], 'r')
    25. except IOError:
    26. print('There was an error opening the file')
    27. sys.exit(1)
    28.  
    29. if (sys.argv[1]).lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.pbm', '.pgm', '.ppm', '.xbm', '.xpm')):
    30. self.initUI()
    31. self.setWindowTitle("shufti")
    32. self.resize(self.img.size())
    33. else:
    34. print("Unsupported file format")
    35. sys.exit(1)
    36.  
    37. def initUI(self):
    38.  
    39. self.img = QPixmap(sys.argv[1])
    40. self.scene = QGraphicsScene()
    41. self.scene.addPixmap(self.img)
    42. self.view = QGraphicsView(self.scene, self)
    43. self.view.resize(self.img.width() + 2, self.img.height() + 2)
    44. self.show()
    45.  
    46. def toggleFullscreen(self):
    47. if self.isFullScreen():
    48. self.showNormal()
    49. else:
    50. self.showFullScreen()
    51.  
    52. def keyPressEvent(self, event):
    53. if event.key() == QtCore.Qt.Key_F11 or event.key() == QtCore.Qt.Key_F:
    54. self.toggleFullscreen()
    55.  
    56.  
    57. if __name__ == '__main__':
    58.  
    59. app = QApplication(sys.argv)
    60. shufti = Shufti()
    61. sys.exit(app.exec_())
    To copy to clipboard, switch view to plain text mode 
    Last edited by danboid; 12th February 2017 at 18:39.

  2. #2
    Join Date
    Dec 2012
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: PyQt: zooming with QGraphicsSceneWheelEvent

    I don't really know Python, however in C++ what I did was override the QGraphicsView class itself and use an instance of that overriden class in my program. Then, in my derived class, I just had to declare the wheelEvent method (overriding the regular method). Then scrolling the wheel starting calling my override.

    One thing I noticed was the the scale method didn't seem to react well to successive calls. Maybe it was me being dumb, but I wound up doing this:

    Qt Code:
    1. QTransform scale;
    2. scale.scale(zoom_level, 1); //scale only one dimension
    3. setTransform(scale);
    To copy to clipboard, switch view to plain text mode 


    Also the wheel data itself turned up coming from the .y() method of the QPoint that comes from the angleDelta() method of the wheelEvent.
    Last edited by Royce; 12th February 2017 at 20:07.

  3. #3
    Join Date
    Feb 2017
    Posts
    6
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: PyQt: zooming with QGraphicsSceneWheelEvent

    Thanks for your suggestions Royce!

    I've now mostly got mousewheel zoom working. My problem now is that when the scaled QGraphicsView object area exceeds the initial QGV view area (ie when you zoom in), the mousewheel switches from zooming in and out to scrolling the image view vertically.

    I presume I need to resize the QGV view area (but not the window size) every time I zoom to stop the view scrollbars appearing but I'm not sure how best to do that yet.


    Qt Code:
    1. #!/usr/bin/python3
    2. # -*- coding: utf-8 -*-
    3. #
    4. # shufti - A WIP, PyQt5 persistent image viewer
    5. #
    6. # By Dan MacDonald
    7. #
    8. # 2017
    9. #
    10. # Usage:
    11. #
    12. # python shufti.py path/to/image
    13.  
    14. import sys
    15. from PyQt5 import QtCore
    16. from PyQt5.QtGui import QPixmap
    17. from PyQt5.QtWidgets import QMainWindow, QApplication, QGraphicsScene, QGraphicsView
    18.  
    19. class Shufti(QMainWindow):
    20.  
    21. def __init__(self):
    22. super().__init__()
    23. try:
    24. self.file = open(sys.argv[1], 'r')
    25. except IOError:
    26. print('There was an error opening the file')
    27. sys.exit(1)
    28.  
    29. if (sys.argv[1]).lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.pbm', '.pgm', '.ppm', '.xbm', '.xpm')):
    30. self.zoom = 1
    31. self.initUI()
    32. self.setWindowTitle("shufti")
    33. self.resize(self.img.size())
    34. else:
    35. print("Unsupported file format")
    36. sys.exit(1)
    37.  
    38. def initUI(self):
    39.  
    40. self.img = QPixmap(sys.argv[1])
    41. self.scene = QGraphicsScene()
    42. self.scene.addPixmap(self.img)
    43. self.view = QGraphicsView(self.scene, self)
    44. self.view.resize(self.img.width() + 2, self.img.height() + 2)
    45. self.show()
    46.  
    47. def toggleFullscreen(self):
    48. if self.isFullScreen():
    49. self.showNormal()
    50. else:
    51. self.showFullScreen()
    52.  
    53. def keyPressEvent(self, event):
    54. if event.key() == QtCore.Qt.Key_F11 or event.key() == QtCore.Qt.Key_F:
    55. self.toggleFullscreen()
    56.  
    57. def wheelEvent(self, event):
    58. self.zoom += event.angleDelta().y()/2880
    59. self.view.scale(self.zoom, self.zoom)
    60.  
    61. if __name__ == '__main__':
    62.  
    63. app = QApplication(sys.argv)
    64. shufti = Shufti()
    65. sys.exit(app.exec_())
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Feb 2017
    Posts
    6
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: PyQt: zooming with QGraphicsSceneWheelEvent

    I have read that QGraphicsView is supposed to automatically expand when any of its components spill over its edges, if I understand correctly but this is not what I'm seeing. When I zoom into an image, the view scrollbars appear and then its game over for the zoom.

    I've tried various things with itemsBoundingRect, sceneRect(), fitInView, BoundingRectViewportUpdate but nothing has improved the situation from the code I've already posted.

  5. #5
    Join Date
    Feb 2017
    Posts
    6
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: PyQt: zooming with QGraphicsSceneWheelEvent

    I have also tried setting

    self.view.setVerticalScrollBarPolicy(QtCore.Qt.Scr ollBarAlwaysOff)
    self.view.setHorizontalScrollBarPolicy(QtCore.Qt.S crollBarAlwaysOff)

    Whilst that hides the scrollbars, it doesn't disable scrolling of the QGV area so it doesn't fix my problem.

  6. #6
    Join Date
    Feb 2017
    Posts
    6
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: PyQt: zooming with QGraphicsSceneWheelEvent

    I've spent all day trying to crack this and seeing as no-one else knows the answer it looks like I'll have to live without the scrollwheel zoom and just do with keyboard shortcuts

    Other things I've tried that I thought might work included setting setInteractive() to False for the QGV object and I also tried overriding the scrollContentsBy method:

    Qt Code:
    1. #!/usr/bin/python3
    2. # -*- coding: utf-8 -*-
    3. #
    4. # shufti - A WIP, PyQt5 persistent image viewer
    5. #
    6. # By Dan MacDonald
    7. #
    8. # 2017
    9. #
    10. # Usage:
    11. #
    12. # python shufti.py path/to/image
    13.  
    14. import sys
    15. from PyQt5 import QtCore
    16. from PyQt5.QtGui import QPixmap
    17. from PyQt5.QtWidgets import QMainWindow, QApplication, QGraphicsScene, QGraphicsView
    18.  
    19. class GraphicsView(QGraphicsView):
    20.  
    21. def __init__(self):
    22. super().__init__()
    23.  
    24. def scrollContentsBy(self, blah, blah):
    25. pass
    26.  
    27. class Shufti(QMainWindow):
    28.  
    29. def __init__(self):
    30. super().__init__()
    31. try:
    32. self.file = open(sys.argv[1], 'r')
    33. except IOError:
    34. print('There was an error opening the file')
    35. sys.exit(1)
    36.  
    37. if (sys.argv[1]).lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.pbm', '.pgm', '.ppm', '.xbm', '.xpm')):
    38. self.zoom = 1
    39. self.initUI()
    40. self.setWindowTitle("shufti")
    41. self.resize(self.img.size())
    42. else:
    43. print("Unsupported file format")
    44. sys.exit(1)
    45.  
    46. def initUI(self):
    47.  
    48. self.img = QPixmap(sys.argv[1])
    49. self.scene = QGraphicsScene()
    50. self.scene.addPixmap(self.img)
    51. self.view = GraphicsView(self.scene, self)
    52. self.view.resize(self.img.width() + 2, self.img.height() + 2)
    53. self.show()
    54.  
    55. def toggleFullscreen(self):
    56. if self.isFullScreen():
    57. self.showNormal()
    58. else:
    59. self.showFullScreen()
    60.  
    61. def keyPressEvent(self, event):
    62. if event.key() == QtCore.Qt.Key_F11 or event.key() == QtCore.Qt.Key_F:
    63. self.toggleFullscreen()
    64.  
    65. def wheelEvent(self, event):
    66. self.zoom += event.angleDelta().y()/2880
    67. self.view.scale(self.zoom, self.zoom)
    68.  
    69. if __name__ == '__main__':
    70.  
    71. app = QApplication(sys.argv)
    72. shufti = Shufti()
    73. sys.exit(app.exec_())
    To copy to clipboard, switch view to plain text mode 

    None of it has stopped the scrolling of the QGV clashing with mousewheel zoom.

  7. #7
    Join Date
    Dec 2012
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: PyQt: zooming with QGraphicsSceneWheelEvent

    In C++ I have to call the accept() method of the QWheelEvent to let Qt know I'm handling the event. ( Or something) Maybe Python isn't doing that for you automatically? I could see that causing an issue like this maybe. Do you have access to accept()? Give it a shot.

  8. #8
    Join Date
    Feb 2017
    Posts
    6
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: PyQt: zooming with QGraphicsSceneWheelEvent

    Thanks for your suggestion Royce!

    I did get it working in the end thanks to a tip-off from Qt overlord Rui Nuno Capella aka RNCBC and so now I've created my new favourite image viewing app, shufti. Its main feature, and the reason it was created, is that it automatically saves and restores the zoom level, rotation, window size, desktop location and the scrollbar positions (ie viewing area) for every image it loads, on a per-image/location basis.

    https://github.com/danboid/shufti

Similar Threads

  1. Replies: 0
    Last Post: 29th January 2015, 10:55
  2. Upgrading from PyQt 4.5 to PyQt 4.7
    By RogerCon in forum Installation and Deployment
    Replies: 0
    Last Post: 14th July 2010, 18:52
  3. zooming only x
    By mastupristi in forum Qwt
    Replies: 1
    Last Post: 7th May 2009, 08:23
  4. Zooming..
    By chethana in forum Qt Programming
    Replies: 7
    Last Post: 10th October 2007, 08:17
  5. Zooming in but not out
    By nitriles in forum Qt Programming
    Replies: 1
    Last Post: 5th October 2007, 08:54

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.