2

在 Android 上测试应用程序时,我注意到发生了一些奇怪的事情。双击事件处理程序一直在触发,而该特定项目上没有发生任何双击。

试图隔离问题时,我发现几乎每一次点击链都像双击一样快速,无论哪个两个对象会导致第二个对象上的第二次点击注册为双击,而实际上它只是一次单击。

下面是一个示例,由一排 3 个随机颜色的矩形组成,每个矩形内部都有一个鼠标区域。每个鼠标区域的双击被操纵以将父矩形的颜色设置为不同的随机颜色。在android下快速单击两个不同的矩形会触发双击和第二个颜色变化。这不会在 Windows 或 Ubuntu Linux 上发生。

Window {
  id: main
  visible: true
  width: 400
  height: 400
  title: qsTr("Hello World")

  Row {
    Rectangle {
      width: main.width * .33
      height: main.height
      color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
      border.color: "black"
      border.width: 2
      MouseArea {
        anchors.fill: parent
        onDoubleClicked: parent.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
      }
    }
    Rectangle {
      width: main.width * .33
      height: main.height
      color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
      border.color: "black"
      border.width: 2
      MouseArea {
        anchors.fill: parent
        onDoubleClicked: parent.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
      }
    }
    Rectangle {
      width: main.width * .33
      height: main.height
      color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
      border.color: "black"
      border.width: 2
      MouseArea {
        anchors.fill: parent
        onDoubleClicked: parent.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
      }
    }
  }
}

看起来好像“上一次单击”或应该用于检测双击的任何属性在不同的鼠标区域之间共享,而不是在每个鼠标区域之间共享。该问题在 Qt 5.7 和 5.7.1 中都有体现。

这绝对是我今年发现的第 10 个 Qt 错误,但我仍然想问一下是否有人知道发生了什么以及如何修复它,因为我需要修复它,而 Qt 错误报告过程并不快。因此,任何想法都非常受欢迎。

4

1 回答 1

3

在通过实际解决方案找到更好的答案之前,了解通过减少双击检测的全局间隔可以在一定程度上减轻此问题对用户体验的破坏性影响可能会很有用。

默认情况下,它是相当昏昏欲睡的 500 毫秒。我发现将其减少到 250 毫秒有助于避免 90% 以上的不正确双击:

QGuiApplication app(argc, argv);
app.styleHints()->setMouseDoubleClickInterval(250);

此外,还有一种快速而简单的 qml-only 方法来创建以下内容的“固定”副本MouseArea

// MArea.qml
Item {
  id: main
  property alias mouseX : ma.mouseX
  property alias mouseY : ma.mouseY
  property alias acceptedButtons: ma.acceptedButtons
  // etc aliases
  signal clicked(var mouse)
  signal doubleClicked(var mouse)
  // etc signals, function accessors
  MouseArea {
    id: ma
    property real lClick : 0
    anchors.fill: parent
    onClicked: {
      var nc = Date.now()
      if ((nc - lClick) < 500) main.doubleClicked(mouse)
      else main.clicked(mouse)
      lClick = nc
    }
  }
}

这个实际上是按预期工作的,并且几乎可以完全“即插即用”与原始版本兼容。

于 2016-12-19T00:31:50.983 回答