Вопрос

В поисках обработки событий (например, движений мыши и щелчков) не путем создания подклассов, необходимо использовать 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");
*/
    }
Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top