Qt RTTI trouble
-
05-07-2019 - |
Question
Dans une quête pour gérer les événements (comme les mouvements de la souris et les clics) non par sous-classement, il faut utiliser installEventFilter
et fournir un gestionnaire d'événements. Ce faisant, j'ai rencontré un problème avec le support RTTI, ce qui signifie que typeid (). Name ()
donne QObject *
à tout moment, quel que soit l'événement de l'objet. a été déclenché. Il y a bien sûr une autre solution --- dynamic_cast
suivie de la vérification null-pointeur, mais personnellement, je ne la trouve pas propre (et souhaiterais éviter plusieurs vérifications de ce type).
Pour être plus précis, voici un exemple que je n’ai pas fait pour utiliser Visual C ++ avec RTTI activé (/ 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");
*/
}
La solution
Utilisez qobject_cast
et / ou obj- > metaObject () - > className ()
à la place.
Autres conseils
je voudrais utiliser
if (obj->metaObject() == &ColorPicker::staticMetaObject) {
...
}
si seules les instances ColorPicker (et non les sous-classes de ColorPicker) sont acceptées.
Si vous acceptez également des sous-classes, utilisez
if (qobject_cast<ColorPicker *>(obj)) {
...
}
Le pointeur doit être déréférencé de sorte que l'objet vers lequel il pointe soit utilisé. Sans déréférencer le pointeur, le résultat sera le type_info pour le pointeur, pas ce à quoi il pointe.
Logger::log(QString("mouse pressed on %1").arg(typeid(*obj).name()));
Vous devriez normalement utiliser typeid
sur le déréférencement d'un pointeur - le typeid
d'un pointeur est calculé au moment de la compilation et n'est normalement pas intéressant.
if ( typeid(*obj) == typeid(ColorPicker) )
Logger::log("color picker clicked");
Cela dit, il n'y a pas beaucoup de différence entre ce que vous faites ici et la route dynamic_cast
- dans tous les cas, vous devrez faire dynamic_cast
à un moment donné. .