【问题标题】:Pass Events Between QML Objects在 QML 对象之间传递事件
【发布时间】:2015-01-10 21:57:07
【问题描述】:

我有一种情况,我想将 QML 事件传递给初始事件处理程序中间的另一个 QML 项。例如

Item {
   id: item1

   Keys.onPressed: {
      // Pre-process...

      passEventToObject(event, item2);

      // Post-process based on results of event passing...
   }
}

TextInput {
   id: item2
   // Expect key press event to be handled by text input
}

我可以做些什么来达到passEventToObject

注意事项:

  • 我无权修改 Keys.onPressed 内的 item2,它是 QML 内置 (TextInput)。
  • 事件传递必须发生在item1.Keys.onPressed中间

【问题讨论】:

    标签: qt qml qevent


    【解决方案1】:

    您可以简单地在您的第一个对象信号处理程序中调用另一个对象的信号:

    Item {
       id: item1
       Keys.onPressed: {
          // Pre-process...
          item2.Keys.pressed(event);
          // Post-process based on results of event passing...
       }
    }
    
    Item {
       id: item2
       Keys.onPressed: {
          // Some other stuff happens here
       }
    }
    

    【讨论】:

    • 谢谢 - 这几乎奏效了。如果我在第二个项目中定义了Keys.onPressed,它将调用该操作,但不会调用父类的操作。我的特殊情况是使用TextInput,当使用此方法时item2 不处理按键。
    【解决方案2】:

    在项目之间移动事件的一种方法是创建一个 C++ 插件并使用QCoreApplication::sendEvent。不幸的是,Qt 不直接从 QML KeyEvent 和 C++ QKeyEvent 映射,所以插件的接口需要暴露事件的内部:

    bool EventRelay::relayKeyPressEvent(
       int key,
       Qt::KeyboardModifiers modifiers,
       const QString& text,
       bool autoRepeat,
       ushort count) const
    {
       QKeyEvent event(QKeyEvent::KeyPress, key, modifiers, text, autoRepeat, count);
       return relayEventToObject(&event, mpTargetObject);
    }
    

    使用它:

    EventRelay { id: relay }
    
    Item {
       id: item1
       Keys.onPressed: {
          // Pre-process...
    
          relay.relayEventToObject(event, item2);
    
          // Post-process...
       }
    }
    
    TextInput {
       id: item2
    }
    

    【讨论】:

    • 我似乎有需要。这个例子对我来说不是很清楚:你编写了一个带有签名的方法的定义,而在 QML 中你调用了一个具有不同名称和签名的方法。也许relayEventToObject 只是一个调用QCoreApplication::sendEvent 的方法,但你能更好地解释一下relayKeyPressEvent 的用途吗?
    【解决方案3】:

    我认为您可以找到here 的“信号到信号连接”部分可能很有用。 基本上,每个信号都有一个connect 方法,可用于创建信号链。

    如果您有兴趣转发关键事件(如您的示例中所示),请考虑使用 forwardTo 属性:

    此属性提供了一种将来自输入法的按键操作、按键释放和键盘输入转发到其他项目的方法。当您希望一个项目处理某些键(例如向上和向下箭头键),而另一个项目处理其他键(例如向左和向右箭头键)时,这可能很有用。一旦已转发键的项目接受该事件,它就不再转发到列表中后面的项目。

    文档提供了一个很好的简单示例。

    【讨论】:

    • forwardTo 属性很有趣,但是在我描述的情况下它不起作用 - 我需要在处理它的过程中将事件转发给另一个对象(不是在开始时或以forwardTo 指示结束)。
    • 对不起,没有考虑代码中的 cmets。我的错。 :) 我不确定是否存在实现您正在搜索的交错的方法。作为一种简单的解决方案,您可以拦截第一项中的事件(预处理)为第二项发出自定义信号,然后在第二项处理结束时,向第一项(后处理)发出另一个自定义信号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 2012-05-08
    • 2017-04-03
    相关资源
    最近更新 更多