3
votes

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.

1
I don't know quite enough to answer this question, but if you uncomment the line and change the numbers to 202 (instead of 200) you don't get scrollbars. Presumably Qt is calculating that a 200px square GraphicsScene doesn't quite fit in a 200px square GraphicsView. Maybe there is a a 1px border to the GraphicsView?three_pineapples

1 Answers

5
votes

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!