1

I am new to QtWidgets and trying to build an app in QtWidgets and Python (3.x). the end goal of the app is to show images and a superposed cursor (to be exact, a "plus" sign of 2cm) that can be moved along the image reacting to mouse events. I concentrate now first on this cursor. So far, I read examples on how to do it on matplotlib. however, i have trouble to understand how to integrate matplotlib on my code. Also, is matplotlib the easiest way to do it on this code. or there might be a better way to do it. any hint would be helpful thank you in advance.

here is my desired output and the code of my app enter image description here

import sys
from PySide2 import QtWidgets
from vispy import scene
from PySide2.QtCore import QMetaObject
from PySide2.QtWidgets import *

class SimpleItem(QtWidgets.QGraphicsItem):
    def __init__(self):
       QtWidgets.QGraphicsItem.__init__(self)
       self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)

       def boundingRect(self):
          penWidth = 1.0
          return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
                         20 + penWidth, 20 + penWidth)

       def paint(self, painter, option, widget):
          rect = self.boundingRect()
          painter.drawRect(rect)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)

        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        self.groupBox = QGroupBox(self.centralwidget)
        self.groupBox.setObjectName("groupBox")

        self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 1)

        MainWindow.setCentralWidget(self.centralwidget)

        QMetaObject.connectSlotsByName(MainWindow)


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # OpenGL drawing surface
        self.canvas = scene.SceneCanvas(keys='interactive')
        self.canvas.create_native()
        self.canvas.native.setParent(self)

        self.view = self.canvas.central_widget.add_view()

        self.view.bgcolor = '#ffffff'   # set the canva to a white background

        scene2 = QGraphicsScene()
        item = SimpleItem()
        scene2.addItem(item)
        self.setWindowTitle('MyApp')


def main():
    import ctypes
    ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('my_gui')

    app = QtWidgets.QApplication([])

    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

edit: I added a class (here it is a rectangle just as an example) to illustrate my problem. i have trouble integrating that snippet of the code (with SimpleItem) to OpenGL canvas

Josh.h
  • 71
  • 1
  • 13
  • If you just want to show images and a cross-hair, then there's no need for matplotlib (which has a different purpose), as the basic [Graphics View Framework](https://doc.qt.io/qt-5/graphicsview.html) is more than sufficient. – musicamante Nov 21 '22 at 00:16
  • i looked into that something like (where SimpleItem can be the cursor) but i have problems understanding how to integrate this scene in my code `scene2 = QGraphicsScene() item = SimpleItem() scene2.addItem(item)` – Josh.h Nov 21 '22 at 08:00
  • I edited the question to illustrate my exact problem – Josh.h Nov 22 '22 at 10:31

1 Answers1

0

You can use the QApplication.setOverrideCursor method to assign a .png image file as your cursor when it appears inside of the Qt program.

Here is an example that is mostly based on the code in your question. And below is a gif that demonstrates the example. And the last image is the image I used in the code as cursor.png

Hope this helps

import sys
from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtGui import *

class SimpleItem(QtWidgets.QGraphicsItem):
    def __init__(self):
       QtWidgets.QGraphicsItem.__init__(self)
       self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
       self._brush = QBrush(Qt.black)

    def boundingRect(self):
        penWidth = 1.0
        return QRectF(-50 - penWidth / 2, -50 - penWidth / 2,
                     50 + penWidth, 50 + penWidth)

    def paint(self, painter, option, widget):
        rect = self.boundingRect()
        painter.drawRect(rect)
        painter.fillRect(rect, self._brush)


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.resize(800, 600)
        self.scene = QGraphicsScene()
        self.canvas = scene.SceneCanvas(keys='interactive')
        self.view = QGraphicsView(self.scene)
        item = SimpleItem()
        self.scene.addItem(item)
        self.setCentralWidget(self.view)
        self.setWindowTitle('MyApp')


def main():
    import ctypes
    ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('my_gui')
    app = QtWidgets.QApplication([])
    app.setOverrideCursor(QCursor(QPixmap('cursor.png')))
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

enter image description here

enter image description here

Alexander
  • 16,091
  • 5
  • 13
  • 29