Question

How do you make a QGraphicsScene with a specified size and a QGraphicsView to monitor that scene with the same size?

This sounds like a stupid question but consider the following test code [1]

import sys
from PyQt4 import QtGui, QtCore

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.scene = QtGui.QGraphicsScene(0, 0, 200, 200, self)
        self.view = QtGui.QGraphicsView(self.scene, self)
        #self.view.setMaximumSize(200, 200)
        self.setCentralWidget(self.view)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

When I run this I get a little window with the QGraphicsView and no scroll bars. If I shrink the window scroll bars appear because I've made the view smaller than the specified size of the scene. If I enlarge the window the bars go away and the view resizes with the window. All of this makes sense.

Now I run the same code again but with the commented line (preceded by #) un-commented. The Window appears with the view inside, but the view has scroll bars. When I shrink the window the view also shrinks, but when I enlarge the window the view only enlarges to a certain size. This is not surprising. What is surprising is that with the view at it's maximum size, the scroll bars are still there. I don't understand this because the maximum size of the view is explicitly matched to the size of the scene in the code.

Why does this happen?

I am aware that other questions have explained how to force the scene and view to fit together but I want to understand what size view and scene I have actually made, hence my attempt to use explicitly specified sizes.

[1] I'm using PyQt, C++ users just read "self" as "this" and "import" as "#include"

EDIT: The accepted answer below is absolutely correct. I would just like to add for others who read this that if your view is in a layout you have to account for the layout margins as well. These can be explicitly set in the QtDesigner etc.

Was it helpful?

Solution

Ok, I worked it out for you!

The QGraphicsView (which subclasses QFrame) has a border. If you add the below line to your init method:

self.view.setFrameShape(QtGui.QFrame.NoFrame)

then you remove the 1px frame and it works as you expect!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top