Resizing the QPainter canvas

Heads up! You've already completed this tutorial.

anonymous | 2020-05-10 20:29:00 UTC | #1

When I resize the window, my QLabel Canvas is not resized, and the drawing coordinates are still coming from the window, not Canvas, so everything is shifted. (5.13.0 on Windows)

Any idea what's wrong? Thanks


Virginia | 2020-05-10 20:33:14 UTC | #2

Adding self.setScaledContents(True) before self.setPixmap(pixmap) will make it fill the window regardless of size, but then it no longer paints.

It looks like there needs to be a SizePolicy. I got this code to work, based on this post on Stack Overflow. https://stackoverflow.com/questions/43569167/pyqt5-resize-label-to-fill-the-whole-window I haven't tried the other suggested method from the same post yet, and I can see from other sites that there are multiple ways of doing it.

I added to the Canvas class some scaling, a size policy, minimum size (needed to allow it to get smaller as well as larger), and resize event. It will also keep the aspect ratio and centres it. It resets the canvas. You can also see in this code 2 lines I commented out - that was where I was experimenting with making it fill the whole window regardless of size.

In addition, @martin has told me that you should be able to get the current pixmap from self.pixmap() (as in the mouseMoveEvent method) and then scale that directly, e.g.

python
def resizeEvent(self, event):
    pixmap = self.pixmap()
    pixmap=pixmap.scaled(self.width(), self.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
    self.setPixmap(pixmap)

I hope this helps!

python
class Canvas(QtWidgets.QLabel):
    def init(self):
        super().init()
        pixmap= QtGui.QPixmap(600,300)
        #pixmap = QtGui.QPixmap(self.width(), self.height())
        pixmap=pixmap.scaled(self.width(),self.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        pixmap.fill(QtGui.QColor('#ffffff'))
        self.setPixmap(pixmap)
        self.pen_color = QtGui.QColor('#000000')
        self.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        self.setAlignment(Qt.AlignCenter)
        self.setMinimumSize(10,10)

    def set_pen_color(self, c):
        self.pen_color = QtGui.QColor(c)

    def mouseMoveEvent(self, e):
        painter = QtGui.QPainter(self.pixmap())
        p = painter.pen()
        p.setWidth(1)
        p.setColor(self.pen_color)
        painter.setPen(p)
        for n in range(SPRAY_PARTICLES):
            xo = random.gauss(0, SPRAY_DIAMETER)
            yo = random.gauss(0, SPRAY_DIAMETER)
            painter.drawPoint(e.x() + xo, e.y() + yo)
        self.update()

    def resizeEvent(self, event):
        pixmap= QtGui.QPixmap(600,300)
        # pixmap = QtGui.QPixmap(self.width(),self.height())
        pixmap.fill(QtGui.QColor('#ffffff'))
        pixmap=pixmap.scaled(self.width(), self.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.setPixmap(pixmap)

Create GUI Applications with Python & Qt5 by Martin Fitzpatrick — (PyQt5 Edition) The hands-on guide to making apps with Python — Over 10,000 copies sold!

More info Get the book

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak

Resizing the QPainter canvas was written by Martin Fitzpatrick .

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt.