Russian Qt Forum
Май 05, 2024, 15:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Реализация простого ткстового QGraphicsItem  (Прочитано 3232 раз)
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« : Ноябрь 06, 2014, 09:42 »

Когда уменьшается количество символов в тексте и происходит перерисовка элемента, кусок предыдущего текста остается. Т.е. рисуется новый текст поверх старого.
Пропает сей артефакт при клике на сцену.

Сам класс:
Код
Java
class TextDesignItem extends QGraphicsItem {
   public TextDesignItem() {
       super();
   }
 
   private String text = new String();
   public void setText(String t) {
       text = t;
       update();
   }
   public String getText() {
       return text;
   }
 
   private QFont font = new QFont();
   public void setFont(QFont f) {
       font = f;
       update();
   }
   public QFont getFont() {
       return font;
   }
 
   @Override
   public QRectF boundingRect() {
       QFontMetricsF fm = new QFontMetricsF(font);
       QRectF rect = fm.boundingRect(text);
       rect.moveTo(0, 0);
       return rect;
   }
 
   @Override
   public void paint(QPainter painter, QStyleOptionGraphicsItem option, QWidget widget) {
       painter.setRenderHint(QPainter.RenderHint.HighQualityAntialiasing, true);
       painter.setFont(font);
       QRectF rect = boundingRect();
       // Добавил 5.0, т.к. текст может не поместиться в rect, и тогда будет обрезан
       rect.setWidth(rect.width() + 5.0);
       painter.drawText(rect, text);
 
       // Нарисуем рамку вокруг элемента
       if (isSelected())
           qt_graphicsItem_highlightSelected(this, painter, option);
   }
}
 

Тыкните в чем проблема, спасибо Улыбающийся
« Последнее редактирование: Ноябрь 06, 2014, 13:51 от gil9red » Записан

Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #1 : Ноябрь 06, 2014, 12:40 »

все просто, нужно при изменении текста вызывать prepareGeometryChange().

вот мой код для примера
Код:
void YourTextItem::setText(const QString & text)
{
 if(p_text!=text)
{
 prepareGeometryChange();
 p_text = text;
}
}

но нужно также переопределить boundingRect() в котором у вас должен возвращаться QRectF который занимается текстом на сцене. Могу посоветовать делать через QFontMetrics.
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #2 : Ноябрь 06, 2014, 12:52 »

если в двух словах, при любом предполагаем изменении размеров элемента на сцене следует вызывать метод prepareGeometryChange() вместо update(), так как update просто заставляет перерисовать сцену элемент со старыми размерами (видать есть какое то кеширование), а prepareGeometryChange говорит сцене, что размер элемента будет меняться, и она дернет все нужные функции для того что бы сцена обновила размер элемента у себя в кеше и перерисовала уже без артефактов. ну и желательно boundingRect вызывать с adjusted(-1,-1,1,1).
Еще может влиять параметр QGraphicsView::setViewportUpdateMode(QGraphicsView::FullViewportUpdate); который заставляет перерисовывать сцену полностью при любых изменениях элементов.
Вроде как щас в любом случае рисуется через OpenGL(начиная с Qt5.0), то этот параметр более целесообразен чем другие.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #3 : Ноябрь 06, 2014, 13:51 »

Fregloin, boundingRect() переопределен, что видно в коде, который приложил Улыбающийся
Заменил update на prepareGeometryChange и все стало правильно перерисовываться, спасибо Улыбающийся
Записан

Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.092 секунд. Запросов: 23.