Search code examples
resizepysideqgraphicsviewqgraphicsscene

PySide: Resizable scene in QGraphicsView


I'm trying to find a way to mark the border of a QGraphicsScene, and make it resizable inside a QGraphicsView, to create something similar to Microsoft Paint.


In other words, my current QGraphicsView looks like this:

Current QGraphicsView

But my image is only this big, as indicated by the red box:

Image size indicated by red box.  The background doesn't count as part of the image.

I want my QGraphicsView to be like this (the little black boxes are cornergrabbers for resizing the canvas):

Final resizable QGraphicsView


Functionally, I want it to be similar to MS Paint: MS Paint example

The canvas (scene) is resizable, and the scrollbars on the window (view) appear when needed. The blue background color (solid gray background) appears behind the canvas.

How would I go about accomplishing this?


To try to get the grey background, I've been experimenting with QGraphicsView.setBackgroundBrush() and QGraphicsScene.setBackgroundBrush(). I've learned that QGraphicsView's background brush completely overrides QGraphicsScene's background brush if one is set. Even if I only set the background brush for QGraphicsScene, that background brush extends over the image's original boundaries.


Here is a link to my test code. Help is appreciated!


Solution

  • I have to struggle with your constructors...dunno if it works on Windows, but have to make it to work with Linux. Try :

    def setPixmap(self, pixmap):
        if self.pixmap_item:
            self.removeItem(self.pixmap_item)
    
        self.pixmap_item = self.addPixmap(pixmap)
    
        self.setPixBackGround()
    
    def setPixBackGround(self):
        # put Background rect for image
        pixR = self.pixmap_item.pixmap().rect()
        bgRectangle = self.addRect(pixR.x()-10, pixR.y()-10, 
                        pixR.width()+20, pixR.height()+20)
        # set color and Z value to put it behind image
        bgColor = QColor(58, 176, 176)
        bgRectangle.setBrush(bgColor)
        bgRectangle.setZValue(-.1)
        # take coordinates for brabbers
        bgR = bgRectangle.rect()
        grab1R = QRect(-5,-5,10,10)
        # put grabbers as wish...
        grab1 = self.addRect(grab1R)
        grab1.setPos(bgR.topLeft())
    
        grab2 = self.addRect(grab1R)
        grab2.setPos(bgR.topRight())
        # ....etc....