3

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);
}

どうもありがとう!

4

2 に答える 2

3

のコメントに注意してください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();
}
于 2011-08-08T12:49:40.893 に答える
0

qgraphicsitem_castを使ってみてください

于 2011-08-08T12:35:38.303 に答える