Вопрос о itemChange () из QGraphicsItem - PullRequest
3 голосов
/ 08 августа 2011

В функции itemChange сначала я получаю дочерний элемент, который будет добавлен, затем использую dynamic_cast для приведения его к MyItem, но приведение всегда завершается неудачей.

 QVariant MyItem::itemChange ( GraphicsItemChange change, const QVariant & value )
{

if (change==ItemChildAddedChange)
{
  QGraphicsItem* item=value.value<QGraphicsItem*>();
if (item)
{
     MyItem* myItem=dynamic_cast<MyItem*>(item);//myItem always be NULL,
//although I know the item is 'MyItem' type.
     if (myItem)
      {
       qDebug()<<"successful!";
       }
       }
}
return QGraphicsItem::itemChange(change,value);
}

Большое спасибо!

Ответы [ 2 ]

3 голосов
/ 08 августа 2011

Обратите внимание на комментарий к itemChange:

Обратите внимание, что новый дочерний элемент может быть не полностью создан, когда уведомление отправлено; Вызов чистых виртуальных функций на ребенка может привести к аварии.

dynamic_cast также может потерпеть неудачу, если объект не полностью построен. (Я не совсем понимаю спецификацию по этому вопросу, но в некоторых случаях это будет, а в некоторых - нет). Если вы установите родителя после построения элемента, он будет работать:

#include <QtGui>

class MyGraphicsItem : public QGraphicsRectItem {
public:
  MyGraphicsItem(QGraphicsItem *parent, QGraphicsScene *scene)
    : QGraphicsRectItem(0.0, 0.0, 200.0, 200.0, parent, scene) {
    setBrush(QBrush(Qt::red));
  }
protected:
  QVariant itemChange(GraphicsItemChange change, const QVariant &value) {
    if (change == QGraphicsItem::ItemChildAddedChange) {
      QGraphicsItem* item = value.value<QGraphicsItem*>();
      if (item) {
        MyGraphicsItem* my_item=dynamic_cast<MyGraphicsItem*>(item);
        if (my_item) {
          qDebug() << "successful!";
        }
      }
    }
    return QGraphicsRectItem::itemChange(change, value);
  }
};

int main(int argc, char **argv) {
  QApplication app(argc, argv);

  QGraphicsScene scene;
  MyGraphicsItem *item = new MyGraphicsItem(NULL, &scene);

  // This will work.
  MyGraphicsItem *item2 = new MyGraphicsItem(NULL, &scene);
  item2->setParentItem(item);

//  // This will not work.
//  MyGraphicsItem *item2 = new MyGraphicsItem(item, &scene);

  QGraphicsView view;
  view.setScene(&scene);
  view.show();

  return app.exec();
}
0 голосов
/ 08 августа 2011

Попробуйте использовать qgraphicsitem_cast

...