PyQt5: я не могу понять setSceneRect (x, y, w, h) QGraphicsScene - PullRequest
1 голос
/ 21 апреля 2019

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

Итак, вот что я делаю:

import sys
from PyQt5.QtWidgets import QApplication, QGraphicsLineItem, 
QGraphicsScene, QGraphicsView


class Demo(QGraphicsView):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(300, 300)

        self.line = QGraphicsLineItem()
        self.line.setLine(0, 0, 100, 100)

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 300, 300)
        self.scene.addItem(self.line)

        self.setScene(self.scene)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

Размер представления - 300x300, и я использую setSceneRect(), чтобы убедиться, что сценаразмер 300x300.

В этом случае источник Сцены находится в верхнем левом углу.enter image description here

Однако, когда я использую setSceneRect(0, 0, 150, 150), источник не там, а в (75, 75)!enter image description here

Почему?Я думал, что первые два параметра setSceneRect(x, y, w, h) устанавливают, где должно быть начало координат.Когда сцена меньше, чем вид, как мы можем убедиться, что источник сцены находится в верхнем левом углу?

Любая помощь будет принята!

1 Ответ

1 голос
/ 21 апреля 2019

Как указывают документы :

выравнивание: Qt :: Alignment

Это свойство содержит выравнивание сцена в представлении, когда видна вся сцена.

Если вся сцена видна на виде (то есть, нет видимых полосы прокрутки,) выравнивание представления решит, где сцена будет представленный в представлении. Например, если выравнивание Qt :: AlignCenter, по умолчанию, сцена будет центрирована в вид, и если выравнивание (Qt :: AlignLeft | Qt :: AlignTop), Сцена будет отображена в верхнем левом углу представления.

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

Таким образом, решение состоит в том, чтобы установить выравнивание по:

import sys
from PyQt5.QtWidgets import QApplication, QGraphicsLineItem, QGraphicsScene, QGraphicsView
from PyQt5.QtCore import Qt

class Demo(QGraphicsView):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(300, 300)

        self.line = QGraphicsLineItem()
        self.line.setLine(0, 0, 100, 100)

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 150, 150)
        self.scene.addItem(self.line)

        self.setScene(self.scene)
        self.setAlignment(Qt.AlignTop | Qt.AlignLeft)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

enter image description here


Пояснение:

Чтобы понять, что это за сцена вначале, нужно понимать, что это QGraphicsView и QGraphicsScene, эти концепции объясняются аналогично записи фильма, QGraphicsView - это камера, QGraphicsScene представляет то, что записано, т.е. сцена. Сцена ограничена sceneRect, если камера находится очень близко к сцене, ее границы не будут соблюдаться, но если камера находится далеко, прямая проекция сцены в камере не займет весь экран, поэтому она будет иметь чтобы выровнять в некоторой позиции, в случае QGraphicsView используется свойство выравнивания.


почему сцена больше не центрируется в виде, если я использую setSceneRect (50, 50, 150, 150)?

Чтобы ответить, я использую следующий пример, где, чтобы сделать сцену видимой, я использую QGraphicsRectItem:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class Demo(QtWidgets.QGraphicsView):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(300, 300)

        self.line = QtWidgets.QGraphicsLineItem()
        self.line.setLine(0, 0, 100, 100)

        self.scene = QtWidgets.QGraphicsScene()
        self.scene.setSceneRect(50, 50, 150, 150)
        self.scene.addItem(self.line)
        rect_item = self.scene.addRect(QtCore.QRectF(50, 50, 150, 150))
        rect_item.setPen(QtGui.QPen(QtGui.QColor("green")))

        self.setScene(self.scene)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

enter image description here

Как вы можете видеть, выравнивание не о QRectF (0, 0, w, h), а о центре QRectF (x, y, w, h), который в этом случае (100,100). Так что сосредоточьтесь на sceneRect в QGraphicsView.

...