Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: wirelesswizard от Апрель 21, 2009, 12:56



Название: Проблема с заливкой QGraphicsRectItem || мерцание
Отправлено: wirelesswizard от Апрель 21, 2009, 12:56
Создаю класс, который public наследует QGraphicsRectItem.
Переопределяю метод void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
При этом полученный результат - отображение прямоугольника на виджете QGraphicsView - оставляет желать лучшего.
Основная проблема заключается в том, что заливка сперва вообще не видна, а затем начинает мерцать по мере изменения геометрии основного окна.
Ниже приведен проблемный код, прошу помочь разобраться!

1. Заголовочный файл класса
Код
C++ (Qt)
class Foo : public QGraphicsRectItem
{
public:
    Foo (QPointF O, double dis = 0);
   ~Foo ();
 
   ...
 
 
   void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
 
private:
   QPointF dot_O_;
   double height_;
 
   const QPointF countRectCenter() const;
   const QRectF countRectPos() const;
 
   ...
 
   QRectF rect_;
};
 
 

2. Исходный код класса
Код
C++ (Qt)
Foo ::Foo (QPointF O, double dis)
:   dot_O_ ( O ),
  height_ ( dis ),
    rect_ ( QRectF(dot_O_.x(), dot_O_.y(), 38, 50) )
{
 
}
 
Foo ::~Foo ()
{}
 
const QPointF Foo ::countRectCenter() const
{
   return QPointF(dot_O_.x(), dot_O_.y() - height_);
}
 
const QRectF Foo ::countRectPos() const
{
   return QRectF(QPointF(countRectCenter().x() - rect_.width()/2, countRectCenter().y() + rect_.height()/2),
                 QPointF(countRectCenter().x() + rect_.width()/2, countRectCenter().y() - rect_.height()/2));
}
 
...
 
void Foo ::paint(QPainter *painter,
                const QStyleOptionGraphicsItem *option,
                QWidget * /* widget */)
{
   rect_ = QRectF(...);
 
   painter->setPen(Qt::black);
   painter->setBrush( Qt::SolidPattern );
   painter->drawRect(rect_);
}
 

3. Пример рисования объекта
Код
C++ (Qt)
...
QMainWindow* mainwgt = new QMainWindow;
 
QGraphicsScene* scene = new QGraphicsScene(0, 0, 210, 220);
QGraphicsView* view = new QGraphicsView(scene);
view->setRenderHint(QPainter::Antialiasing, true);
mainwgt->setCentralWidget(view);
 
Foo* foobar = new Foo( QPointF(scene->width() / 2, scene->height()), 12.1 );
scene->addItem(foobar);
 
mainwgt->show();
...
 

Спасибо.


Название: Re: Проблема с заливкой QGraphicsRectItem || мерцание
Отправлено: pastor от Апрель 21, 2009, 13:01
/* offtop */

wirelesswizard, классно оформил пост! Так держать! Будет как пример хорошего оформления :)


Название: Re: Проблема с заливкой QGraphicsRectItem || мерцание
Отправлено: Rcus от Апрель 21, 2009, 13:29
Самое интересно осталось за точками:
как рассчитывается rect_?
зачем наследоваться от QGraphicsRectItem и не использовать его pen, brush и rect?
где boundingRect?


Название: Re: Проблема с заливкой QGraphicsRectItem || мерцание
Отправлено: Khs от Апрель 21, 2009, 13:44
/* offtop */

wirelesswizard, классно оформил пост! Так держать! Будет как пример хорошего оформления :)

Тока для заголовков шрифт бы поменьше :)


Название: Re: Проблема с заливкой QGraphicsRectItem || мерцание
Отправлено: wirelesswizard от Апрель 21, 2009, 14:03
Самое интересно осталось за точками:
как рассчитывается rect_?
зачем наследоваться от QGraphicsRectItem и не использовать его pen, brush и rect?
где boundingRect?

Добавил в шапку код методов рассчета rect_.

На какой стадии следует пользоваться унаследованными pen, brush и rect?

Что именно даст переопределение метода boundingRect?

Спасибо за быстрый ответ.


Название: Re: Проблема с заливкой QGraphicsRectItem || мерцание
Отправлено: Rcus от Апрель 21, 2009, 14:23
Вот смотрю я и все меньше понимаю зачем нужно было порождать потомка. То что есть вполне реализуется фабричным методом.


Название: Re: Проблема с заливкой QGraphicsRectItem || мерцание
Отправлено: wirelesswizard от Апрель 21, 2009, 14:36
Я хочу в дальнейшем перейти с QGraphicsRectItem на QGraphicsPixmapItem, чтобы реализовать "текстуру".
Именно поэтому и использую наследование...
Дополнительный вопрос: мне необходимо поворачивать прямоугольник на произвольный угол.
Очевидное решение - матричное преобразование, например, можно добавить:
Код
C++ (Qt)
   setTransform(QTransform().translate( dot_O_.x(),  dot_O_.y()).rotate(myAngle)
                            .translate(-dot_O_.x(), -dot_O_.y()));
 
в определение метода paint(...).
Но что происходит с координатами прямоугольника на самом деле? Такое ощущение, как будто меняется лишь отображение прямоугольника, а его координаты считаются прежними.
Кроме того, после трансформации (поворота) прямоугольника появляется ещё одна визуальная проблема. Кроме мерцания заливки - ещё и мерцание всего прямоугольника (всё что повёрнуто то и дело исчезает с виджета). При некоторых размерах окна всё становится видно.
Что именно стоит поменять, чтобы прекратилось мерцание?
Спасибо.


Название: Re: Проблема с заливкой QGraphicsRectItem || мерцание
Отправлено: Rcus от Апрель 21, 2009, 14:41
Прочитайте статью в Assistant -> "The Graphics View Framework". I mean it