题
在寻求处理事件(如鼠标移动和点击)而不是通过子类化时,必须使用 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-&gt; metaObject() - &gt; 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
不隶属于 StackOverflow