Qt RTTI проблема - PullRequest
       26

Qt RTTI проблема

2 голосов
/ 11 сентября 2009

В квесте для обработки событий (например, движений мыши и щелчков) не путем подклассов, нужно использовать installEventFilter и предоставить обработчик событий. При этом я столкнулся с проблемой поддержки RTTI, что означает, что typeid().name() дает QObject * все время, независимо от того, какое событие объекта было инициировано. Есть, конечно, другое решение - dynamic_cast, за которым следует проверка нулевого указателя, но лично я не нахожу это чистым (и хотел бы избежать нескольких таких проверок). Чтобы быть более конкретным, вот пример, который я не сделал для работы с Visual C ++ с включенным RTTI (/ 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");
*/
    }

Ответы [ 4 ]

4 голосов
/ 11 сентября 2009

Используйте qobject_cast и / или obj->metaObject()->className() вместо.

1 голос
/ 12 сентября 2009

Указатель должен быть разыменован для использования объекта, на который он указывает. Без разыменования указателя результатом будет указатель type_info для указателя, а не то, на что он указывает.

Logger::log(QString("mouse pressed on %1").arg(typeid(*obj).name())); 
1 голос
/ 11 сентября 2009

Я бы использовал

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

если принимаются только экземпляры ColorPicker (а не подклассы ColorPicker).

Если вы также принимаете подклассы, используйте

if (qobject_cast<ColorPicker *>(obj)) {
  ...
}
0 голосов
/ 11 сентября 2009

Обычно вы должны использовать typeid при разыменовании указателя - typeid указателя вычисляется во время компиляции и обычно не представляет интереса.

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

Тем не менее, нет большой разницы между тем, что вы здесь делаете, и маршрутом dynamic_cast - в любом случае вам придется сделать dynamic_cast в какой-то момент.

...