質問
サブクラス化ではなく、イベント(マウスの移動やクリックなど)を処理するためのクエストでは、 installEventFilter
を使用してイベントハンドラーを提供する必要があります。その間、RTTIサポートで問題が発生しました。つまり、どのオブジェクトイベントに関係なく、 typeid()。name()
は常に QObject *
を提供します。トリガーされました。もちろん、別の解決策があります--- dynamic_cast
に続いてヌルポインターチェックがありますが、個人的にはきれいではありません(複数のこのようなチェックを避けたい)。
具体的には、RTTIが有効(/ GR)のVisual C ++で動作するように作成しなかった例を次に示します。
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-&gt; metaObject()-&gt; className()
代わりに。
他のヒント
使用します
if (obj->metaObject() == &ColorPicker::staticMetaObject) {
...
}
ColorPicker-instances(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
をしなければなりません。