Question

In a quest for handling events (like mouse moves and clicks) not by subclassing, one has to use installEventFilter and provide an event handler. While doing so, I've encountered a problem with RTTI support, meaning that typeid().name() gives QObject * all the time, no matter on which object event was triggered. There is, of course, another solution---dynamic_cast followed by null-pointer check, but personally I don't find it clean (and would like to avoid multiple such checks). To be more specific, here is an example I didn't make to work with Visual C++ with RTTI enabled (/GR):

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");
*/
    }
Was it helpful?

Solution

Use qobject_cast and/or obj->metaObject()->className() instead.

OTHER TIPS

I would use

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

if only ColorPicker-instances (and not subclasses of ColorPicker) is be accepted.

If you are accepting subclasses too, use

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

The pointer must be dereferenced so that the object it points to is used. Without dereferencing the pointer, the result will be the type_info for the pointer, not what it points to.

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

You should normally use typeid on the dereference of a pointer - the typeid of a pointer is calculated at compile time and is not normally interesting.

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

That said, there isn't much difference between what you are doing here, and the dynamic_cast route - in any case you will have to do dynamic_cast at some point.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top