自定义QGraphicItem和重绘问题 [英] Custom QGraphicItem and Repaint Issues

查看:1342
本文介绍了自定义QGraphicItem和重绘问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

全部,我实现了一个多边形的QGraphicsItem。然而,我现在在 update()中遇到困难,因此我使用 QGraphicsEllipseItem c $ c>功能。我的代码发布在结尾,我的问题是:


  1. 我在这里采取正确的方法吗?我开始怀疑自己

  2. 我应该在我的实现中调用 QGraphicsItem :: update()我称之为

其他一些信息:




  • 我做了一个脏的小黑客。在我的实际代码中,我还继承了 QObject 。这允许我在场景()(我知道已经使用 itemChange )设置 eventFilter 。从场景中我在鼠标移动期间过滤 QGraphicsSceneMouseEvent 并且调用 QGraphicsItem :: update()否则我的行不会

  • 当我从场景中删除我的 InteractivePolygon 时,我的行不会被删除!我必须调用scene() - > update。我觉得有点不对。






声明:

  class InteractivePolygon:public QGraphicsItem 
{

public:
//只有重要的方法
QRectF boundingRect()const;
void paint(bla bla bla);
bool eventFilter(QObject *,QEvent *);

private:
QList< QGraphicsEllipseItem *> m_points;

void AddPolygonPoint(QPointF);
QGraphicsEllipseItem * MakeNewPoint(QPointF);
}

实施:

  QRectF InteractivePolygon :: boundingRect()const 
{
return childrenBoundingRect();
}

void InteractivePolygon :: paint(QPainter painter .. otherstuf)
{
QPen line_pen(QColor(255,0,0));
painter-> setPen(line_pen);

if(m_points.count()> 1)
{
for(int i = 1; i painter-> drawLine(m_points [i-1] - > pos(),m_points [i] - > pos());
}
}

void AddPolygonPoint(QRectF point)
{
QGraphicsEllipseItem * new_item = MakeNewPoint(point);
new_item-> setParent(this);

m_points-> push_front(new_item);

update();
}

QGraphicsEllipseItem * InteractivePolygon :: MakeNewPoint(QPointF& new_point)
{
QGraphicsEllipseItem * result = 0;
result = new QGraphicsEllipseItem();
result-> setPos(new_point);
result-> setRect(-4,-4,8,8);
result-> setFlags(QGraphicsItem :: ItemIsMovable | QGraphicsItem :: ItemIsSelectable)

return result;
}

//假设这个方法正确设置/存在
bool InteractivePolygon :: eventFilter(QObject * object,QEvent * event)
{
if(event-> type()== QEvent :: QEvent :: GraphicsSceneMouseMove)
{
QGraphicsSceneMouseEvent * mouse_move =(QGraphicsSceneMouseEvent *)event;
//所选索引设置为else,让我们假设它工作
if(selected_index)
{
update(); //如果我不这样做,我的paint()中的行不重绘。
}
}
}


解决方案>

解决方案是 prepareGeometryChange()每次我改变任何东西,我的项目,将改变其边界框。



这允许我删除所有 update()调用。 p>

All, I implemented a QGraphicsItem which is a polygon. I sped up development by using QGraphicsEllipseItem as the points (for the dragging capabilities.) However, I am now having difficulty in update() functionality. My code is posted at the end, my questions are:

  1. Am I taking the right approach here? I am starting to doubt myself
  2. Am I supposed to be calling QGraphicsItem::update() in my implementation? I call it alot

Some other info:

  • I did a dirty little hack. In my actual code I also inherit from QObject. This allows me to install an eventFilter on the scene() (which I know has been set using itemChange). From the scene I filter QGraphicsSceneMouseEvent during mouse moves and call QGraphicsItem::update() otherwise my lines wouldn't be redrawn.
  • When I remove my InteractivePolygon from the scene now, my lines are not removed! I have to call scene()->update. I feel like something's not right.

declaration:

class InteractivePolygon : public QGraphicsItem
{

public:
   //Only important methods
   QRectF boundingRect() const;
   void paint(bla bla bla);
   bool eventFilter(QObject *, QEvent *);

private:
   QList<QGraphicsEllipseItem *> m_points;

   void AddPolygonPoint(QPointF);
   QGraphicsEllipseItem * MakeNewPoint(QPointF);
}

implementation:

QRectF InteractivePolygon::boundingRect() const
{
   return childrenBoundingRect();
}

void InteractivePolygon::paint(QPainter painter.. otherstuf)
{
   QPen line_pen(QColor(255,0,0));
   painter->setPen(line_pen);

   if(m_points.count() > 1)
   {
      for(int i = 1; i < m_points.count(); ++i)
          painter->drawLine(m_points[i-1]->pos(), m_points[i]->pos());
   }
}

void AddPolygonPoint(QRectF point)
{
   QGraphicsEllipseItem * new_item = MakeNewPoint(point);
   new_item->setParent(this);

   m_points->push_front(new_item);

   update();  
}

QGraphicsEllipseItem * InteractivePolygon::MakeNewPoint(QPointF & new_point)
{
   QGraphicsEllipseItem * result = 0;
   result = new QGraphicsEllipseItem();
   result->setPos(new_point);
   result->setRect(-4, -4, 8, 8);
   result->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable)

   return result;
}

//Lets pretend this method is correctly setup/exists
bool InteractivePolygon::eventFilter(QObject *object, QEvent *event)
{
   if(event->type() == QEvent::QEvent::GraphicsSceneMouseMove)
   {
      QGraphicsSceneMouseEvent * mouse_move = (QGraphicsSceneMouseEvent *)event;
      //Selected index is set else, let's assume it works
      if(selected_index)
      {
         update(); //If I don't do this, my lines in my paint() are not redrawn.
      }
   }
}

解决方案

The solution was prepareGeometryChange() everytime I changed anything in my item that would change its bounding box. Everything is redrawn correctly and updated as necessary.

This allowed me to remove all update() calls.

这篇关于自定义QGraphicItem和重绘问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆