Frage

In einer quest für die Handhabung von events (wie der Maus bewegt und Klicks), nicht durch Unterklassen verwenden installEventFilter und geben Sie ein Ereignis-handler.Dabei habe ich ein problem mit RTTI-Unterstützung, was bedeutet, dass typeid().name() gibt QObject * die ganze Zeit, egal auf welches Objekt Ereignis ausgelöst wurde.Es ist natürlich auch eine Lösung---dynamic_cast gefolgt von einem null-Zeiger überprüfen, aber ich persönlich finde es nicht sauber (und möchten vermeiden, dass Sie mehrere solcher Prüfungen).Um genauer zu sein, hier ist ein Beispiel, das ich nicht machen, um die Arbeit mit Visual C++ mit RTTI aktiviert (/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");
*/
    }
War es hilfreich?

Lösung

Verwenden qobject_cast und/oder obj->metaObject()->className() statt.

Andere Tipps

Ich würde verwenden

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

wenn nur ColorPicker-Instanzen (und nicht den Unterklassen der ColorPicker) ist werden akzeptiert.

Wenn Sie akzeptieren Unterklassen zu verwenden

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

Der Zeiger muss aufgelöst werden, so dass das Objekt, das es Punkte verwendet.Ohne Dereferenzierung der Zeiger, wird das Ergebnis der type_info für die Zeiger, nicht das, was es zeigt.

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

Sie sollten in der Regel verwenden typeid auf die Dereferenzierung eines Zeigers - der typeid der eine Zeiger ist berechnet bei der Kompilierung und ist in der Regel nicht interessant.

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

Das heißt, es gibt nicht viel Unterschied zwischen dem, was Sie hier tun, und die dynamic_cast route - in jedem Fall werden Sie zu tun haben dynamic_cast an einem gewissen Punkt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top