【问题标题】:Handling Qt C++ events in QML context在 QML 上下文中处理 Qt C++ 事件
【发布时间】:2016-12-20 10:13:28
【问题描述】:

C++ API 具有QEvent 以及从它派生的多个其他类(QMouseEventQGestureEvent 等)。另一方面,QML 也有事件。但是,我正在努力寻找一种在 QML 中直接处理 C++ 事件的优雅方式。

通常我所做的是创建一个自定义QQuickWidget(或类似的,包括QQmlEngine),覆盖QWidget::event(QEvent* event),并在接收到特定的C++事件后,我通过信号将它传播到QML插槽并加载QML代码通过那个小部件。这似乎需要做很多工作,我想知道是否有某种 QML 内置事件处理来处理来自 C++ 上下文的事件。

我对在 QML 中处理 QGestureEvents 尤其感兴趣,但我猜对这种类型的事件有效的方法也应该适用于任何其他类型的事件。

【问题讨论】:

  • 您尝试过使用MultiPointTouchArea 吗?它有一个信号 gestureStarted(GestureEvent gesture) 可能会满足您的需求。
  • 问题是我想捕捉真正来自 C++ 上下文的手势事件。例如,如果我将数据从设备(只能通过 C++ 方式访问)映射到 Qt 的手势 API,然后将其传递到应用程序的 QML 部分。它甚至可能没有远程连接到触摸(例如使用 Kinect 设备做出手势)。
  • “这似乎需要做很多工作”——与为 QML 实现 C++ 事件处理所需的工作量相比,这实际上是没有

标签: c++ qt events qml


【解决方案1】:

QML 中没有对事件处理的直接支持,甚至可以通过辅助对象访问键盘和鼠标。

QEvent 本身不是QObject 派生的,因此同样适用于所有派生事件。这意味着没有元信息,也没有从 QML 使用的简单方法。

由于您对特定类型的事件感兴趣,因此最简单的方法是为这些类型的事件创建自己的辅助对象,用 C++ 实现它并通过可以附加处理程序的信号将其与 QML 接口。

【讨论】:

  • 好的,就直接的解决方案而言,这似乎是一个不可行的情况。这至少证实了我担心我必须通过信号将事件数据重新路由到 QML 插槽。谢谢。我不得不想知道到底 QML 事件是如何实现的。似乎这些不是基于QEvents 而是其他的东西......
  • @rbaleksandar - 正如答案所述,这是通过辅助对象完成的。例如,MouseArea 仅用于鼠标和单点触摸事件。
  • 啊,是的。对于那个很抱歉。谢谢。我想我可能会这样做,看看它是如何工作的。
【解决方案2】:

如果QGestureEvent 可以复制构造,您可以简单地创建一个基于Q_GADGET 的适配器:

class QmlGestureEvent : public QGestureEvent
{
    Q_GADGET
    Q_PROPERTY(...) // for the things you want to access from QML

public:
    QmlGestureEvent(const QGestureEvent &other) : QGestureEvent(other) {}
};

如果它不是可复制构造的,则必须将数据成员添加到适配器并从事件中复制值。

【讨论】:

  • 没有事件支持复制构造。这是实施例如状态机框架。因此,Qt 在一些地方内部实现了事件克隆。希望它会在 Qt 6 中得到清理。
  • @KubaOber 啊,我明白了。我刚刚看到QEvent 本身有一个复制构造函数,而QGestureEvent 似乎没有删除它,所以我想象编译器会创建一个调用基类的默认值,然后为派生类型的数据进行成员复制
  • 这样说吧:有一个拷贝构造函数。但不支持。您必须审核 Qt 代码以确保您打算复制的任何事件实际上都是可复制的。另一个问题是,虽然具体的事件类型可能是可复制的,但您真正需要的是虚拟复制构造函数(clone,它采用 QEvent)。
  • 在这种情况下,“复制”更像是演员表,因为小工具类不添加任何成员。实际上可能与演员一起工作。
猜你喜欢
  • 1970-01-01
  • 2014-09-29
  • 2017-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多