PyQt: Попытка понять графическую сцену/представление

Я пытаюсь понять QGraphicsView и QGraphicsScene, в частности, как разместить графические элементы и показать их там, где я их хочу. Я также смущен, когда появятся полосы прокрутки, если сцена больше, чем область просмотра.

Например, этот бит кода создаст небольшой графический вид с эллипсом в верхнем углу:

import sys
from PyQt4 import QtGui, QtCore

class MyView(QtGui.QGraphicsView):
    def __init__(self):
        QtGui.QGraphicsView.__init__(self)

        self.scene = QtGui.QGraphicsScene(self)
        self.scene.setSceneRect(QtCore.QRectF(0, 0, 245, 245))

        self.setScene(self.scene)

        self.item = QtGui.QGraphicsEllipseItem(0, 0, 60, 40)
        self.scene.addItem(self.item)


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

Однако, если self.scene.setSceneRect(QtCore.QRectF(0, 0, 245, 245)) опущен, то эллипс появляется в середине окна, хотя эллипс имеет x, y = 0,0. Я не знаю, почему! Есть ли причина для такого поведения?

Аналогично, я запутался в появлении полос прокрутки, когда размер сцены больше, чем вид. Например, следующий код создает представление/сцену с несколькими эллипсами, а itemsBoundingRect больше, чем sceneRect. Отображаются только некоторые из эллипсов, но нет полосы прокрутки, чтобы увидеть скрытые, вам нужно увеличить размер окна. Но когда вы это делаете, размещение эллипсов сдвигается, поэтому x, y эллипсов игнорируются.

import sys
from PyQt4 import QtGui, QtCore

class MyView(QtGui.QGraphicsView):
    def __init__(self):
        QtGui.QGraphicsView.__init__(self)

        self.setGeometry(QtCore.QRect(100, 100, 250, 250))

        self.scene = QtGui.QGraphicsScene(self)
        self.scene.setSceneRect(QtCore.QRectF(0, 0, 200, 200))

        self.setScene(self.scene)

        for i in range(5):
            self.item = QtGui.QGraphicsEllipseItem(i*75, 10, 60, 40)
            self.scene.addItem(self.item)


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

Если строка self.scene.setSceneRect(QtCore.QRectF(0, 0, 200, 200)) опущена, появится полоса прокрутки. Но опять же, позиции x, y эллипсов игнорируются, и они сосредоточены в представлении.

То, что я пытаюсь сделать, - это создать представление, в котором элементы идут туда, где я их хочу, и если количество элементов приводит к тому, что сцена больше размера вида, для появления полос прокрутки, но для x, y позиции объектов, которые будут поддерживаться.

Мне кажется, что мне не хватает какой-то важной части головоломки вида/сцены...

Ответ 1

Из документа

Если прямая смены сцены не установлена, PySide.QtGui.QGraphicsScene будет использовать ограничительную область всех > элементов, как это было возвращено PySide.QtGui.QGraphicsScene.itemsBoundingRect(), в качестве прямоугольника сцены.

Таким образом, он задает прямоугольник вашего изображения в качестве источника сцены, а центр сцены - это центр виджета.

Полосы прокрутки появятся, когда размер сцены больше размера виджета. Когда вы закомментируете строку setSceneRect, ваша сцена будет автоматически изменена, но когда у вас будет линия, ваши изображения будут добавлены за пределы scenRect, поэтому вам нужно будет обновить ваш sceneRect, чтобы показать его.

Ответ 2

import sys 
from PyQt4 import QtGui, QtCore

class MyView(QtGui.QGraphicsView):
    def __init__(self):
        QtGui.QGraphicsView.__init__(self)

        self.setGeometry(QtCore.QRect(100, 100, 600, 250))

        self.scene = QtGui.QGraphicsScene(self)
        self.scene.setSceneRect(QtCore.QRectF())

        self.setScene(self.scene)

        for i in range(5):
            self.item = QtGui.QGraphicsEllipseItem(i*75, 10, 60, 40)
            self.scene.addItem(self.item)


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