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

Я пытаюсь разобраться в 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 положения объектов, которые необходимо сохранить.

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

Ответы [ 2 ]

3 голосов
/ 29 февраля 2012

Из документа

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

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

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

1 голос
/ 12 марта 2015
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_())
...