2009-09-11 53 views
1

在寻求处理事件(如鼠标移动和点击)而不是子类化时,必须使用installEventFilter并提供一个事件处理程序。在这样做的时候,我遇到了RTTI支持的问题,这意味着typeid().name()总是给出QObject *,无论触发哪个对象事件。当然,还有另外一个解决方案--- dynamic_cast,接着是空指针检查,但是我个人并不觉得它很干净(并且希望避免多次这样的检查)。 具体而言,这里是我没有使用Visual C++启用RTTI工作的一个例子(/ GR):Qt RTTI问题

bool 
MousePressInterface::eventFilter 
    (QObject *obj, 
    QEvent *event) 
{ 
    if (event->type() == QEvent::MouseButtonPress) 
    { 
     ColorPicker *sender; 
     sender = dynamic_cast<ColorPicker *> (obj); 

     if (sender) 
     { 
      QColor newColor = 
       QColorDialog::getColor(sender->color()); 
      if (newColor.isValid()) 
         sender->setColor(newColor); 
      Logger::log("color picker clicked"); 
      return true; 
     } 
/* TODO: cleaner way, doesn't work for some reason! 
     Logger::log(QString("mouse pressed on %1").arg(typeid(obj).name())); 
     Logger::log(QString(" checking for %1").arg(typeid(ColorPicker *).name())); 

     if (typeid(obj) == typeid(ColorPicker *)) 
      Logger::log("color picker clicked"); 
*/ 
    } 

回答

3

改为使用qobject_cast和/或obj->metaObject()->className()

+0

谢谢!这正是我一直在寻找的! – MadH 2009-09-11 08:16:25

0

通常应该对指针的反引用使用typeid - 的typeid的一个指针是在编译时计算的,通常不会有意思。

if (typeid(*obj) == typeid(ColorPicker)) 
    Logger::log("color picker clicked"); 

这就是说,没有你在这里做什么,和dynamic_cast路线太大的区别 - 在任何情况下,你将不得不在某些时候做dynamic_cast

+0

是的,我也试过这种方式。 为什么我更喜欢'typeid'的方式是,你可以得到.name()作为一个字符串,然后它只是字符串比较所有我想处理的情况,而不是再次投射... – MadH 2009-09-11 08:11:24

1

我会用

if (obj->metaObject() == &ColorPicker::staticMetaObject) { 
... 
} 

如果只是颜色拾取 - 实例(颜色拾取,而不是子类)被接受。

如果你接受过多的子类,使用

if (qobject_cast<ColorPicker *>(obj)) { 
    ... 
} 
1

指针必须解除引用,以便于使用它指向的对象。在不提取指针的情况下,结果将是指针的type_info,而不是它指向的内容。

Logger::log(QString("mouse pressed on %1").arg(typeid(*obj).name()));