在Android

时间:2016-12-25 20:44:27

标签: android qt qml mousearea

我需要在没有物理键盘的平板设备上模拟控制键按下。为了做到这一点,我有一个屏幕浮动按钮,用户可以使用它来实现这一目标。

问题是,只有一个MouseArea接收触摸事件。如果一个人有焦点,其余的都会被忽略。这显然是有问题的,因为这使得无法按住控制按钮并按下其他GUI元素。

请注意,我不需要在文字上下文中进行多点触控 - 每个鼠标区域只需要一次触摸,我只需要多个鼠标区域即可同时工作。这个,以及MultiPointTouchArea的API专门针对实际的多点触控量身定制的原因,缺少我实际需要的属性,功能(悬停,光标)和便利性,这是我真的不太理由的原因渴望使用它,即使被认为与鼠标输入向后兼容。

我怀疑这种限制是因为触摸已经被强加到MouseArea而不是一等公民,而底层实现是一个游标到规则 - 所有 - 所有有点交易,但是,也许有一些方法可以使多个鼠标区域同时工作?

好的,这是一个简单的例子 - 按下屏幕的左侧或右侧分别将其转为蓝色和红色,但是如果另一个已按下则无法按下一个。

Window {
  id: main
  visible: true
  width: 600
  height: 300

  Row {
    Rectangle {
      width: main.width * .5
      height: main.height
      color: m1.pressed ? "blue" : "black"
      MouseArea {
        id: m1
        anchors.fill: parent
      }
    }
    Rectangle {
      width: main.width * .5
      height: main.height
      color: m2.pressed ? "red" : "black"
      MouseArea {
        id: m2
        anchors.fill: parent
      }
    }
  }
}

1 个答案:

答案 0 :(得分:0)

好吧,两年之后,再也没有答案...我将讲述我的整个历史,因此没有人会尝试我们做过的相同事情,并且浪费时间。跳到该行下方(在图像下方一点)以跳过该行。

我们遇到了同样的问题,甚至更大,因为我们用您说的短语设计了整个系统,

  

即使可以与鼠标输入向后兼容

请记住,看到我们遇到麻烦之后的时间。

考虑了如何解决问题后,我们首先尝试使用递归函数搜索所有鼠标区域,然后为每个触摸点生成一个伪造的鼠标事件,该事件的标记为 Qt.MouseEventSynthesizedByApplication ,然后可能会使用mousearea处理该事件并触发相应的回调。

在这里,我放置了失败代码的图像,所以匆忙的人们不要复制它……它尚未完成,我们仍然有问题想出如何处理多次触摸。 Failed code

当您在鼠标区域中进行多次触摸时,似乎没有为该场景编码的行为,这是有道理的,因为您在系统中应该只有一只鼠标。

然后,我们在网络中进行搜索,并在qt论坛的webarchive的某个类似问题的人的webarchive中找到了一条已删除的2009年帖子,并发布了奇怪的代码(不适用于qt5)欺骗鼠标区域来接受这些事件。这给了我们产生自己的事件的想法,并使用假鼠标事件从相应的鼠标区域调用信号。

pressed(鼠标事件鼠标)信号外,其他均有效,无法触发。它给出了错误。

之后,我们试图公开信号(通过在鼠标区域上显式声明)

property var toques = []
visible: false
property var pressed
onPressed: pressed = true
onReleased: pressed = false

这使我们更加接近,但是这将需要执行每个鼠标事件,而且,这是所有触摸之间的间歇(因为我们可能会为每次触摸触发每个信号),并且行为可能不确定。同样,由于触摸过程中没有顺序来跟踪发生的事情,因此我们拒绝了此区域的鼠标区域。


然后,我们要做的是使用 MutiPointTouchArea 处理事件。我们看到,使用多个MultiPointTouchArea(s)不会产生错误,并且可以处理多次点击(来自触摸)。

您要做的就是用Multitouch替换MouseAreas,并实现您想要的所有行为,在这种情况下,像hover这样的概念就没有意义了,因为我们正在处理触摸。您可能会用压力做类似的事情。我们放置组件 Rectangle 来保留我们感兴趣的变量/信号,并在发生某些操作时从MultiTouchArea进行更改。在这里,我将基于该思想来实现您的琐碎示例:

Window {
  id: main
  visible: true
  width: 600
  height: 300

  Row {
    Rectangle {
      width: main.width * .5
      height: main.height
      property var lol: false
      color: ispressed ? "blue" : "black"
      MultiPointTouchArea {
        id: m1
        anchors.fill: parent
        onPressed: parent.ispressed= true
        onReleased: parent.ispressed= false
      }
    }
    Rectangle {
      width: main.width * .5
      height: main.height
      x:main.width * .5
      property var ispressed: false
      color: ispressed ? "red" : "black"
      MultiPointTouchArea {
        id: m2
        anchors.fill: parent
        onPressed: parent.ispressed= true
        onReleased: parent.ispressed= false
      }
    }
  }
}

如您所见,矩形(您的按钮或其他按钮)具有重要的属性,在这种情况下,被压,并且根据我们定义的行为,它由子项(MultipointToucArea)进行更改,在这种情况下,当按下它时会激活它,在释放时会释放,请注意,在这种情况下,仅通过拉动一根手指就可以使颜色消失,因为会触发onReleased。

在每种情况下,您可能必须决定哪种才是适合您的应用程序的行为。在我们的案例中,为此编程提供的信号已经足够了:

canceled(list<TouchPoint> touchPoints)
gestureStarted(GestureEvent gesture)
pressed(list<TouchPoint> touchPoints)
released(list<TouchPoint> touchPoints)
touchUpdated(list<TouchPoint> touchPoints)
updated(list<TouchPoint> touchPoints)

另外,您可能会看到按下仅发生在被触摸的第一个区域,因此,如果您在其他鼠标区域上按住手指,则不会触发按下事件,因此,使用updated()进行播放可能会能够知道它是否应该激活事物。

这是我们得到的解决方案,并且为我们工作,我们无法找到更好的解决方案,对于单击/按下事件,这就是窍门。

希望有帮助。