Есть ли способ заставить drawText() обновить ограничивающий прямоугольник QPicture?

Рисование на QPicture должно обновить его ограничивающий прямоугольник. Так:

>>> picture = QPicture()
>>> painter = QPainter(picture)
>>> picture.boundingRect()
QRect(0,0,0,0)
>>> painter.drawRect(20,20,50,50)
>>> picture.boundingRect()
QRect(20,20,50,50)

Но если я рисую на нем текст, ограничивающий прямоугольник не обновляется:

>>> picture = QPicture()
>>> painter = QPainter(picture)
>>> picture.boundingRect()
QRect(0,0,0,0)
>>> painter.drawText(10,10, "Hello, World!")
>>> picture.boundingRect()
QRect(0,0,0,0)

Очевидно, что он не обновляет ограничивающий прямоугольник.

Есть ли способ заставить его отображать нарисованный текст или мне нужно сделать это вручную? (Не слишком сложно, но я надеюсь, что Qt сможет мне здесь помочь.)


person Georg Schölly    schedule 27.04.2009    source источник
comment
Какую версию PyQt вы используете? drawText не является методом QPicture в 4.3 и более поздних версиях.   -  person    schedule 27.04.2009
comment
Я имел в виду painter.drawText(), извините. Я использую Qt 4.4. (Новейшая версия, поддерживаемая PyQt.)   -  person Georg Schölly    schedule 27.04.2009
comment
Хорошо, смотрите мой ответ, возможно, это то, что вы ищете.   -  person    schedule 27.04.2009


Ответы (2)


Взгляните на эти перегруженные методы, где вы должны указать ограничивающий прямоугольник после текстового параметра (который явно отличается от прямоугольника в позиции первого аргумента):

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

QPainter.drawText (1), QPainter.drawText (2)

Обновление:

Оказывается, если вы хотите заранее сгенерировать ограничивающий прямоугольник для метода drawText(), вы просто вызываете метод boundingRect() в QPainter, который делает следующее:

Возвращает ограничивающий прямоугольник текста, как он будет отображаться при рисовании внутри заданного прямоугольника с указанными флагами с использованием текущего установленного шрифта(); т. е. функция сообщает вам, где функция drawText() будет рисовать при наличии тех же аргументов.

Если текст не помещается в заданный прямоугольник с использованием указанных флагов, функция возвращает нужный прямоугольник.

QPainter.boundingRect

Я связался с BoundingRect с выводом QRectF, но информация применима и к другим версиям.

В общем, передайте результат QPainter.boundingRect() в параметр boundingRect метода QPainter.drawText() (второй аргумент QRect).

Обновление 2:

Я ИЗВИНЯЮСЬ за то, что был таким чертовски тупым. Я забыл, что drawText работает в PyQt иначе, чем в Qt. Ограничивающий прямоугольник ВОЗВРАЩАЕТСЯ функцией drawText (не передается, как Qt), и, кроме того, вы должны указать флаги выравнивания, прежде чем вы получите возвращаемый вам ограничивающий прямоугольник. (Я даже включил p.end() в соответствии с комментарием Аарона Дигуллы):

pic = Qt.QPicture()
p = QtGui.QPainter(pic)
brect = p.drawText(10,10,200,200, QtCore.Qt.AlignCenter, "blah")
p.end()
print brect
print pic.boundingRect()

Вот результат:

PyQt4.QtCore.QRect(100, 103, 20, 14)

PyQt4.QtCore.QRect(0, 0, 0, 0)

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

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

person Community    schedule 27.04.2009
comment
Дело в том, что ограничивающий прямоугольник QPicture обновляется после любой операции, кроме рисования текста. Я знаю, что могу получить ограничивающий прямоугольник текста с помощью этих функций. - person Georg Schölly; 27.04.2009
comment
Я пытался намекнуть, что это невозможно. Я снова обновил свой ответ, так как я сделал ошибку, сославшись на неверный документ C++ для вашего кода PyQt. - person ; 27.04.2009
comment
Спасибо за ваши усилия! Сейчас я не нашел идеального решения (установка ограничивающего прямоугольника вручную отключает автоматическое обновление), но еще раз спасибо. - person Georg Schölly; 28.04.2009
comment
спасибо за правки @ekhumoro - я довольно долго не участвовал в игре QT / PyQT, и приятно видеть, что эти ответы получают столь необходимые правки - person ; 21.01.2017

Рисование не меняет размер чего-либо в Qt. Основная причина в следующем:

  • Компонент должен рисовать сам себя
  • Краска вызывает изменение размера
  • Изменение размера вызывает рисование -> бесконечный цикл

Таким образом, изменение размера должно произойти на этапе макета. После этого границы не должны меняться.

Чтобы решить вашу проблему, используйте QFontMetric, чтобы выяснить, насколько большим будет ваш текст во время или близко к построению вашего изображения, а затем соответствующим образом измените его размер.

[EDIT] Хм... попробуйте вызвать end() перед запросом ограничивающего прямоугольника. Если это работает, вы нашли ошибку (не видите причины, по которой ограничивающий прямоугольник не должен существовать при добавлении элементов...)

person Aaron Digulla    schedule 27.04.2009
comment
Я рисую на QPicture, который не имеет фиксированного размера, но вычисляет прямоугольник вокруг всех элементов. Я думаю, вы ошибочно принимаете QImage за QPicture. - person Georg Schölly; 27.04.2009