如何正确读取触摸事件并在 QWidget Qt 上获得位置
How to properly read touch events and get position on a QWidget Qt
我正在尝试在 qt 中为 android 应用程序开发游戏控制器,但遇到了一些问题。当我只使用 QMouseEvents 而不是 QTouchEvents 时,控制器工作得很好,但问题是它不支持多点接触。触摸事件似乎没有 QWidget::mousePressEvent 的等价物。我被告知要使用 QWidget::event 而不是这样。
bool GameController::event(QEvent* event)
{
switch(event->type())
{
case QEvent::TouchBegin:
//Do something...
break;
case QEvent::TouchEnd:
//Do something else...
break;
case QEvent::TouchUpdate:
//Do something else...
break;
}
return QWidget::event(event);
}
问题在于我无法使用 event->touchPoints() 来获取触摸的位置,因为它不知道这是一个触摸事件。如何正确读取触摸事件?
编译器可能不知道这是一个触摸事件,但只要你知道,你就可以向下转换:
case QEvent::TouchBegin:
{
QTouchEvent * te = static_cast<QTouchEvent *>(event);
// now you can call te->touchPoints(), etc here
}
请注意,如果 event
实际上未指向 QTouchEvent
(或其子类),则上述代码将调用未定义的行为,因此请仅在可能的情况下使用 static_cast
100% 保证 event
实际上是一个 QTouchEvent(在这种情况下你可以做到这一点)。
对于无法保证向下转换有效的情况,您可以使用 dynamic_cast
代替,它足够智能来检查指向对象和 return NULL
如果向下转换为该类型实际上无效:
case QEvent::TouchBegin:
{
QTouchEvent * te = dynamic_cast<QTouchEvent *>(event);
if (te)
{
// now you can call te->touchPoints(), etc here
}
}
当然,运行时检查会花费几个 CPU 周期,所以除非需要,否则不要使用 dynamic_cast
。
QWidget
(例如 QWidget::showEvent(QShowEvent*)
、QWidget::hideEvent(QHideEvent*)
)的各种类型事件的所有受保护 functions/event 处理程序都是一般 QWidget::event()
的特化方便您使用的方法。
而QWidget::event()
本身就是通过QObject::eventFilter()
虚方法实现的。您可以在此处阅读更多相关信息 - https://doc.qt.io/qt-5/qobject.html#eventFilter. Through the help of bool eventFilter(QObject *obj, QEvent *ev) override
, you can get notified about all QEvents
that are sent to your QObect
as well as to other objects through the use of QObject::installEventFilter().
在 QObject::eventFilter()
的实现主体中,您检查事件的类型及其接收者,然后按照@所述执行 static_cast
或 dynamic_cast
Jeremy Friesner 访问特定于该事件的方法。使用这种强大的机制,如果您希望子类 QObject
在发生事件时发出信号,您可以实现自己的专用事件函数以及自定义信号。
我正在尝试在 qt 中为 android 应用程序开发游戏控制器,但遇到了一些问题。当我只使用 QMouseEvents 而不是 QTouchEvents 时,控制器工作得很好,但问题是它不支持多点接触。触摸事件似乎没有 QWidget::mousePressEvent 的等价物。我被告知要使用 QWidget::event 而不是这样。
bool GameController::event(QEvent* event)
{
switch(event->type())
{
case QEvent::TouchBegin:
//Do something...
break;
case QEvent::TouchEnd:
//Do something else...
break;
case QEvent::TouchUpdate:
//Do something else...
break;
}
return QWidget::event(event);
}
问题在于我无法使用 event->touchPoints() 来获取触摸的位置,因为它不知道这是一个触摸事件。如何正确读取触摸事件?
编译器可能不知道这是一个触摸事件,但只要你知道,你就可以向下转换:
case QEvent::TouchBegin:
{
QTouchEvent * te = static_cast<QTouchEvent *>(event);
// now you can call te->touchPoints(), etc here
}
请注意,如果 event
实际上未指向 QTouchEvent
(或其子类),则上述代码将调用未定义的行为,因此请仅在可能的情况下使用 static_cast
100% 保证 event
实际上是一个 QTouchEvent(在这种情况下你可以做到这一点)。
对于无法保证向下转换有效的情况,您可以使用 dynamic_cast
代替,它足够智能来检查指向对象和 return NULL
如果向下转换为该类型实际上无效:
case QEvent::TouchBegin:
{
QTouchEvent * te = dynamic_cast<QTouchEvent *>(event);
if (te)
{
// now you can call te->touchPoints(), etc here
}
}
当然,运行时检查会花费几个 CPU 周期,所以除非需要,否则不要使用 dynamic_cast
。
QWidget
(例如 QWidget::showEvent(QShowEvent*)
、QWidget::hideEvent(QHideEvent*)
)的各种类型事件的所有受保护 functions/event 处理程序都是一般 QWidget::event()
的特化方便您使用的方法。
而QWidget::event()
本身就是通过QObject::eventFilter()
虚方法实现的。您可以在此处阅读更多相关信息 - https://doc.qt.io/qt-5/qobject.html#eventFilter. Through the help of bool eventFilter(QObject *obj, QEvent *ev) override
, you can get notified about all QEvents
that are sent to your QObect
as well as to other objects through the use of QObject::installEventFilter().
在 QObject::eventFilter()
的实现主体中,您检查事件的类型及其接收者,然后按照@所述执行 static_cast
或 dynamic_cast
Jeremy Friesner 访问特定于该事件的方法。使用这种强大的机制,如果您希望子类 QObject
在发生事件时发出信号,您可以实现自己的专用事件函数以及自定义信号。