Как получить непрозрачную область PyQt QGraphicsTextItem

self.boundingRect() дайте мне размеры пунктирной линии, показанные на изображении. мне нужно получить непрозрачную область (где нарисован фактический текст) я пытался получить

self.opaqueArea()

но он возвращает объект QPainterPath, который кажется довольно сложным и, по-видимому, не имеет функций ширины или высоты и т. д. в качестве представления сложных объектов пути. В. Есть ли более простой способ вычислить это. любые идеи .. заранее спасибо простой способ получить прямоугольник синей области

print ("TEXT BOUNDING RECT:",self.boundingRect())
print ("TEXT OPAQUE AREA  :",self.document().size())
print ("TEXT OPAQUE AREA BR size  :",self.opaqueArea().boundingRect().size())

выход:

TEXT BOUNDING RECT: PyQt5.QtCore.QRectF(0.0, 0.0, 590.0, 56.0)
TEXT OPAQUE AREA  : PyQt5.QtCore.QSizeF(590.0, 56.0)
TEXT OPAQUE AREA BR size  : PyQt5.QtCore.QSizeF()

person haseeb    schedule 17.02.2019    source источник


Ответы (1)


QGraphicsTextItem внутри использует QTextDocument для управления текстом. Вы можете получить к нему доступ через .document(). Текстовый документ имеет свойство size, которое возвращает QPointF.

 self.document().size()

К сожалению, все методы для этого документа возвращают стандартный прямоугольник ограничивающей рамки. Однако можно настроить текстовое поле под размер содержащегося в нем текста. Это не совсем соответствует уровню пикселей (из-за заполнения высоты строки), но близко.

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class MainWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.view = QGraphicsView()

        scene = QGraphicsScene()

        t = QGraphicsTextItem("Sample\n Text")
        font = t.font()
        font.setPointSize(40)
        font.setWeight(600)
        t.setFont(font)
        t.setTextWidth(400)
        scene.addItem(t)

        rect = t.boundingRect()
        r = QGraphicsRectItem(rect)
        r.setPen(QColor('red'))
        scene.addItem(r)

        d = t.document()
        d.setDocumentMargin(0)
        d.adjustSize()
        rect = t.boundingRect()

        r = QGraphicsRectItem(rect)
        r.setPen(QColor('blue'))
        scene.addItem(r)


        self.view.setScene(scene)

        self.setCentralWidget(self.view)




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

Вышеизложенное даст следующий результат —

Изображение, показывающее исходную ограничивающую рамку и обрезанную.

Единственная другая идея, которая у меня была, заключалась в том, чтобы получить QPainterPath из текстового документа и вычислить это QRect, но, похоже, это не так легко доступно. В качестве альтернативы можно было бы нарисовать его до QPainter и обрезать там, но в Qt нет встроенной функции обрезки.

person mfitzp    schedule 17.02.2019
comment
я пробовал это, и document().size() возвращал ту же ограничивающую рамку. на самом деле я хотел получить размеры синего прямоугольника, я выделил, я вижу, это не непрозрачно, но все же это минимальная область, где происходит рисование. - person haseeb; 17.02.2019
comment
@лала, это странно. Я обновил ответ другим параметром, который получает ограничивающий прямоугольник пути художника. - person mfitzp; 17.02.2019
comment
спасибо за помощь, я редактирую вопрос и помещаю туда код/вывод. Также, если вам интересно, зачем мне это нужно, рендеринг ffmpeg (текстовый фильтр) сделал это с текстом. поэтому второй вариант, который приходит мне на ум, - это добавить смещения на основе процента размера шрифта, чтобы приблизиться к совершенству пикселей. - person haseeb; 17.02.2019
comment
@lala снова обновилась, приближаясь. Может достаточно близко? - person mfitzp; 17.02.2019