Keren Meron
Keren Meron

Reputation: 139

Drawing points on QPixmap on QWidget (pyqt5)

I have a QWidget with a QLayout on which there is a QLabel. I set a QPixmap on the label. Wherever the user clicks on the image, I want to draw a point. I defined mouseReleaseEvent (which works) and paintEvent (but no points are drawn). I've read all similar questions and none of the solutions worked for me. Any help? My relevant code:

class ImageScroller(QtWidgets.QWidget):

    def __init__(self, img):
        QtWidgets.QWidget.__init__(self)
        main_layout = QtWidgets.QVBoxLayout()
        self._image_label = QtWidgets.QLabel()
        self._set_image(img)
        main_layout.addWidget(self._image_label)
        main_layout.addStretch()
        self.setLayout(main_layout)

    def _set_image(self, img):
        img = qimage2ndarray.array2qimage(img)
        qimg = QtGui.QPixmap.fromImage(img)
        self._img_pixmap = QtGui.QPixmap(qimg)
        self._image_label.show()

    def paintEvent(self, paint_event):
        painter = QtGui.QPainter(self)
        painter.begin(self)
        painter.setPen(QtGui.QPen(QtCore.Qt.red))
        pen = QtGui.QPen()
        pen.setWidth(20)
        painter.setPen(pen)
        painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
        painter.drawPoint(300,300)
        painter.drawLine(100, 100, 400, 400)
        for pos in self.chosen_points:
            painter.drawPoint(pos)
        painter.end()

    def mouseReleaseEvent(self, cursor_event):
        self.chosen_points.append(QtGui.QCursor().pos())
        self.update()

Upvotes: 2

Views: 7091

Answers (1)

eyllanesc
eyllanesc

Reputation: 244282

When you use QtGui.QCursor.pos() is getting the coordinates of the cursor with respect to the screen, but when you want to paint a widget you must be in the coordinates of the widget, for it the widget has the mapToGlobal() method:

self.mapFromGlobal(QtGui.QCursor.pos())

But in this case there is another solution, you must use the event that returns mouseReleaseEvent that has the information in the pos() method:

cursor_event.pos()

Another problem is that the label you created is above the widget so you do not see the points, the easiest thing is to draw the QPixmap directly with the drawPixmap() method.

Complete code:

from PyQt5 import QtWidgets, QtGui, QtCore


class ImageScroller(QtWidgets.QWidget):
    def __init__(self):
        self.chosen_points = []
        QtWidgets.QWidget.__init__(self)
        self._image = QtGui.QPixmap("image.png")

    def paintEvent(self, paint_event):
        painter = QtGui.QPainter(self)
        painter.drawPixmap(self.rect(), self._image)
        pen = QtGui.QPen()
        pen.setWidth(20)
        painter.setPen(pen)
        painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
        painter.drawPoint(300, 300)
        painter.drawLine(100, 100, 400, 400)
        for pos in self.chosen_points:
            painter.drawPoint(pos)

    def mouseReleaseEvent(self, cursor_event):
        self.chosen_points.append(cursor_event.pos())
        # self.chosen_points.append(self.mapFromGlobal(QtGui.QCursor.pos()))
        self.update()


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = ImageScroller()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

enter image description here

Upvotes: 3

Related Questions