【问题标题】:A question about 'itemChange()' of QGraphicsItem关于 QGraphicsItem 的 'itemChange()' 的问题
【发布时间】:2011-08-08 20:49:40
【问题描述】:

在itemChange函数中,我先获取要添加的子item,然后使用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);
}

非常感谢!

【问题讨论】:

    标签: qt qgraphicsitem


    【解决方案1】:

    注意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();
    }
    

    【讨论】:

    • 非常感谢!你是对的,它失败了,因为在构造函数中使用了'dynamic_cast'..link。因为'itemChange'会在QGraphicsItem的构造函数中被调用,到那时'Myitem'还没有被形成(构造),所以它会失败。
    【解决方案2】:

    尝试使用qgraphicsitem_cast

    【讨论】:

    • 您是否为您的类定义了一个用户类型,如示例中所示?
    • 谢谢你的回复,我用'qgraphicsitem_cast'测试过,也失败了。因为'qgraphicsitem_cast'使用的'type()'函数是'virtual',所以根据qdoc,在'ItemChildAddChange'和'ItemChildRemovedChange'中使用'virtual'函数是错误的。戴夫的回答是正确的,无论如何非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 2010-12-08
    • 2021-11-29
    相关资源
    最近更新 更多