处理触摸事件但也让它通过的对象 [英] Object to process touch event but also let it through
问题描述
我想创建一个像 MultiPointTouchArea
一样工作的对象(所以它会有 touchUpdated 信号)但它也不会窃取触摸,所以放置在它下面的对象也会接收到触摸事件.
I want to create an object that will work like MultiPointTouchArea
(so it will have touchUpdated signal) but also it would not steal touches, so that objects placed beneath it will receive the touch events as well.
解决方案可能需要创建 C++ 对象.
The solution may require creating C++ object.
有没有一种简单的方法来创建这样的对象?是否可以在不窃取"事件的情况下处理(触摸)事件?任何提示将不胜感激.
Is there a simple way to create such object? Is it possible to process (touch) events without "stealing" them? Any hint will be appreciated.
这是我正在尝试做的一个例子.我想触摸顶部 Rectangle
但同时我想要两个 MultiPointTouchArea
的进程触摸:
Here is an example of what I am trying to do. I want to touch top Rectangle
but at the same time I want both MultiPointTouchArea
s process touches:
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
visible: true
width: 300
height: 300
Rectangle {
id: rectangle1
anchors.centerIn: parent
width: 150
height: width
color: "red"
MultiPointTouchArea {
anchors.fill: parent
mouseEnabled: false
onTouchUpdated: {
console.log("Bottom touch area contains:",
touchPoints.length,
"touches.")
}
}
}
Rectangle {
id: rectangle2
anchors.centerIn: parent
width: 100
height: width
color: "blue"
MultiPointTouchArea {
anchors.fill: parent
mouseEnabled: false
onTouchUpdated: {
console.log("Top touch area contains:",
touchPoints.length,
"touches.")
}
}
}
}
如果我能找到可行的解决方案,我会在此处发布.我现在将尝试实现 Mitch 的 解决方案.
If I will find working solution I will post it here. I will be trying now to implement Mitch's solution.
推荐答案
你可以继承 QQuickItem
并覆盖 touchEvent()
函数:
You can subclass QQuickItem
and override the touchEvent()
function:
可以在子类中重新实现此事件处理程序以接收项目的触摸事件.事件信息由event参数提供.
This event handler can be reimplemented in a subclass to receive touch events for an item. The event information is provided by the event parameter.
您可能需要明确设置 accepted
到 false
以确保该项目不会窃取事件:
You'll probably need to explicitly set accepted
to false
to ensure that the item doesn't steal the events:
设置accept参数表示事件接收者想要该事件.不需要的事件可能会传播到父小部件.默认情况下,isAccepted() 设置为 true,但不要依赖它,因为子类可能会选择在其构造函数中清除它.
Setting the accept parameter indicates that the event receiver wants the event. Unwanted events might be propagated to the parent widget. By default, isAccepted() is set to true, but don't rely on this as subclasses may choose to clear it in their constructor.
<小时>
我可以验证上述操作会导致下触摸区域在按下后处理所有事件(在 Android 手机上测试).在这种情况下,您需要以某种方式过滤事件.一种方法是,在您的 QQuickItem 子类中,声明一个将用于指向下部触摸区域的属性.当该属性发生变化时,在触摸区域安装一个事件过滤器:
I can verify that the above will result in the lower touch area taking all events after the press (tested on an Android phone). In that case, you'll need to filter the events somehow. One way to do this is, inside your QQuickItem subclass, declare a property that will be used to point to the lower touch area. When that property changes, install an event filter on the touch area:
main.cpp:
#include <QGuiApplication>
#include <QtQuick>
class CustomTouchArea : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QQuickItem *targetTouchArea READ targetTouchArea WRITE setTargetTouchArea NOTIFY targetTouchAreaChanged)
public:
CustomTouchArea() :
mTargetTouchArea(0) {
}
bool eventFilter(QObject *, QEvent *event) {
if (event->type() == QEvent::TouchUpdate) {
qDebug() << "processing TouchUpdate...";
}
// other Touch events here...
return false;
}
QQuickItem *targetTouchArea() const {
return mTargetTouchArea;
}
void setTargetTouchArea(QQuickItem *targetTouchArea) {
if (targetTouchArea == mTargetTouchArea)
return;
if (mTargetTouchArea)
mTargetTouchArea->removeEventFilter(this);
mTargetTouchArea = targetTouchArea;
if (mTargetTouchArea)
mTargetTouchArea->installEventFilter(this);
emit targetTouchAreaChanged();
}
signals:
void targetTouchAreaChanged();
private:
QQuickItem *mTargetTouchArea;
};
int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<CustomTouchArea>("App", 1, 0, "CustomTouchArea");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
#include "main.moc"
main.qml:
import QtQuick 2.3
import QtQuick.Window 2.2
import App 1.0
Window {
visible: true
width: 300
height: 300
Rectangle {
id: rectangle1
anchors.centerIn: parent
width: 150
height: width
color: "red"
MultiPointTouchArea {
id: touchArea
anchors.fill: parent
mouseEnabled: false
onTouchUpdated: {
console.log("Bottom touch area contains:",
touchPoints.length,
"touches.")
}
}
}
Rectangle {
id: rectangle2
anchors.centerIn: parent
width: 100
height: width
color: "blue"
CustomTouchArea {
targetTouchArea: touchArea
anchors.fill: parent
}
}
}
您可以在这里阅读更多关于事件过滤器的信息.
You can read more about event filters here.
这篇关于处理触摸事件但也让它通过的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!