Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: developer-nsk от Октябрь 13, 2009, 17:04



Название: Как определить геометрический размер текста перед его отображением?
Отправлено: developer-nsk от Октябрь 13, 2009, 17:04
Господа, суть проблемы: мне необходимо создать QGraphicsItem, который будет отображать надписи к графическим объектам. Надпись рисуется на фоне прямоугольника, размер которого зависит от геометрического размера текста. Как можно определить размер текста во время создания объекта-надписи? Если определять в методе paint(), то при первой прорисовке получается коряво... Сейчас я это делаю так: в методе paint() родителя (тоже QGraphicsItem) с помощью метода painter->boundingRect() определяю размер текста и передаю его потомку, дабы предок рисуется раньше, чем потомок-надпись. Вроде работает, но выглядит ужасно коряво. Карта большая, объектов много, надписей соответственно тоже много, приходится писать такую фигню для каждого объекта... Нет ли какого-то более изящного и удобного решения данной проблемы? Заранее благодарен.


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: pastor от Октябрь 13, 2009, 17:06
Размеры текста можно определить через QFontMetrics::boundingRect. А чем QGraphicsTextItem неустроил?


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: developer-nsk от Октябрь 13, 2009, 17:10
Размеры текста можно определить через QFontMetrics::boundingRect. А чем QGraphicsTextItem неустроил?

Он, может, и устроил бы, но в силу неопытности программирования на Qt, данный класс был каким-то образом мною упущен из виду :-) Спасибо за подсказку!


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: developer-nsk от Октябрь 13, 2009, 17:34
Размеры текста можно определить через QFontMetrics::boundingRect. А чем QGraphicsTextItem неустроил?

Попробовал QGraphicsTextItem... Не совсем то, что нужно, если честно. А можно попросить немножко подробнее по поводу QFontMetrics::boundingRect? Как этот метод можно использовать в конструкторе объекта QGraphicsItem?


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: pastor от Октябрь 13, 2009, 17:49
Попробовал QGraphicsTextItem... Не совсем то, что нужно, если честно.

Можно поинтересоваться, чем не устроил?


А можно попросить немножко подробнее по поводу QFontMetrics::boundingRect? Как этот метод можно использовать в конструкторе объекта QGraphicsItem?

Нужно переопределить метод QGraphicsItem::boundingRect примерно таким образом:

Код
C++ (Qt)
QRectF YourItem::boundingRect(void) const
{
   QFontMetrics fm(font());
   return fm.boundingRect(text());
}

font() - возвращает текущий шрифт для отображения надписи
text() - текст надписи


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: developer-nsk от Октябрь 13, 2009, 18:11

Можно поинтересоваться, чем не устроил?

К сожалению, в этом классе не нашёл явного решения проблемы...

Нужно переопределить метод QGraphicsItem::boundingRect примерно таким образом:

Код
C++ (Qt)
QRectF YourItem::boundingRect(void) const
{
   QFontMetrics fm(font());
   return fm.boundingRect(text());
}

font() - возвращает текущий шрифт для отображения надписи
text() - текст надписи

Спасибо за предложенный вариант, но QGraphicsItem не имеет метода font(), в этом-то вся проблема. Пытался в конструкторе создавать QPainter и далее пробовать, как Вы предлагали выше - работает, но в дебаг, естесственно, выводится куча надписей о том, что QPainter не активен (лично мне эти сообщения не мешают, но я не думаю, что их наличие - это хорошо). Можно ли как-то убрать эти сообщения? Ниже код класса:

Код:
#include <QGraphicsScene>

Legend::Legend(QGraphicsItem *parent, QString caption) :
        QGraphicsItem(parent) {
setCacheMode(DeviceCoordinateCache);
setZValue(8);
        //angle=10000.0;
this->setFlag(QGraphicsItem::ItemIgnoresTransformations, true);
this->caption = caption;
        QPainter p;
        QFontMetrics fm(p.font());
        QRectF rect=fm.boundingRect(caption);
        this->myrect=rect;
}

void Legend::setRect(QRectF rect) {
this->myrect = rect;
}

void Legend::setCaption(QString caption) {
this->caption = caption;
update();
}

QString Legend::getCaption() {
return this->caption;
}

QRectF Legend::boundingRect() const {
        return this->myrect;
}

QPainterPath Legend::shape() const {
QPainterPath path;
path.addRect(this->myrect);
return path;
}

void Legend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                QWidget *widget) {
        if (this->myrect == QRectF(0, 0, 1000, 30)) {
QRectF rect = painter->boundingRect(QRect(0, 0, 1000, 30),
this->caption);
this->myrect.setWidth(rect.width() + 4);
this->myrect.setHeight(rect.height() + 2);
        } else {
painter->setRenderHints(QPainter::Antialiasing, false);
painter->setPen(QPen(Qt::black, 0));
painter->setBrush(Qt::white);
painter->drawRect(this->myrect);
painter->drawText(this->myrect.x() + 3, this->myrect.y()
+ this->myrect.height() - 3, this->caption);
        }
}


Заранее Вам премного благодарен!


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: BRE от Октябрь 13, 2009, 18:24
[off]
Камрады, простите за вопрос, но уж очень хочется узнать....  ;)
В последнее время все чаще стал замечать, что народ везде использует конструкцию this->...
Для чего? Много свободного времени, набирать постоянно this->? Кто вас этому учит?
/* я знаю один случай когда необходимо такое уточнение. Для чего это вставлять везде? */
Еще раз извиняюсь, правда интересно.  :)
[/off]


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: Rcus от Октябрь 13, 2009, 18:27
Наверно чтобы лишний раз напомнить себе о контексте используемого символа :) Впрочем если не пользоваться нотацией то действительно по названию нельзя отделить метод от свободной функции, а член класса от глобальной/локальной переменной.


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: Igors от Октябрь 13, 2009, 18:33
Так модно в Жабе :)


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: developer-nsk от Октябрь 13, 2009, 18:37
[off]
Камрады, простите за вопрос, но уж очень хочется узнать....  ;)
В последнее время все чаще стал замечать, что народ везде использует конструкцию this->...
Для чего? Много свободного времени, набирать постоянно this->? Кто вас этому учит?
/* я знаю один случай когда необходимо такое уточнение. Для чего это вставлять везде? */
Еще раз извиняюсь, правда интересно.  :)
[/off]


Согласен, можно и без этого обойтись... Лично у меня эта привычка выработалась тогда, когда я ещё не помнил наизусть большинство методов, которые мне нужны, соответственно QtCreator (и Eclipse тоже) после this и точки вываливает список свойств и методов класса... Это раз. И второй момент - пару раз долбался с дебагом кода, где свойство класса и переменная назывались одинаково. Компилятору-то может и было понятно кто есть кто, а вот мне это чрезвычайно осложнило дебаг большого куска кода :-) Отсюда, вероятно, и появилась такая привычка лично у меня... Не думаю, что это очень плохо как для читабельности кода, так и для удобства работы :-)


*добавлено:
To Igors: И насчёт жабы согласен, довольно долго писал на ней :-)


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: pastor от Октябрь 13, 2009, 18:44
Спасибо за предложенный вариант, но QGraphicsItem не имеет метода font(), в этом-то вся проблема.

Да, я знаю, но нам никто не мешает нам его определить :)

ЗЫ: по умолчанию юзается QApplication::font()


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: pastor от Октябрь 13, 2009, 18:48
Пытался в конструкторе создавать QPainter и далее пробовать, как Вы предлагали выше - работает, но в дебаг, естесственно, выводится куча надписей о том, что QPainter не активен (лично мне эти сообщения не мешают, но я не думаю, что их наличие - это хорошо). Можно ли как-то убрать эти сообщения? Ниже код класса:

ненужен здесь паинтер

Код
C++ (Qt)
....
QFontMetrics fm(QApplication::font ());
QRectF rect=fm.boundingRect(caption);
...


Название: Re: Как определить геометрический размер текста перед его отображением?
Отправлено: developer-nsk от Октябрь 13, 2009, 18:51

ненужен здесь паинтер

Код
C++ (Qt)
....
QFontMetrics fm(QApplication::font ());
QRectF rect=fm.boundingRect(caption);
...

Всё получилось! Премного Вам благодарен!  :)