problemas Qt RTTI
-
05-07-2019 - |
Pergunta
Em uma busca de manipulação de eventos (como movimentos e cliques do mouse) não por subclasse, um tem que usar installEventFilter
e fornecer um manipulador de eventos. Enquanto isso, eu encontrei um problema com suporte RTTI, o que significa que typeid().name()
dá QObject *
o tempo todo, não importa em qual evento objeto foi acionado. Há, naturalmente, uma outra solução --- dynamic_cast
seguido por cheque nulo ponteiro, mas pessoalmente eu não encontrá-lo limpo (e gostaria de evitar vários desses cheques).
Para ser mais específico, aqui está um exemplo que eu não fiz para o trabalho com o Visual C ++ com RTTI habilitado (/ 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");
*/
}
Solução
Use qobject_cast
e / ou obj->metaObject()->className()
vez.
Outras dicas
Gostaria de usar
if (obj->metaObject() == &ColorPicker::staticMetaObject) {
...
}
Se apenas ColorPicker-casos (e não subclasses de ColorPicker) é ser aceite.
Se você está aceitando subclasses também, uso
if (qobject_cast<ColorPicker *>(obj)) {
...
}
O ponteiro deve ser dereferenced para que o objeto que aponta para é usado. Sem dereferencing o ponteiro, o resultado será o type_info para o ponteiro, não o que ele aponta.
Logger::log(QString("mouse pressed on %1").arg(typeid(*obj).name()));
Você deve usar normalmente typeid
na dereference de um ponteiro -. A typeid
de um ponteiro é calculado em tempo de compilação e não é normalmente interessante
if ( typeid(*obj) == typeid(ColorPicker) )
Logger::log("color picker clicked");
Dito isso, não há muita diferença entre o que você está fazendo aqui, e a rota dynamic_cast
-., Em qualquer caso, você terá que fazer dynamic_cast
em algum ponto