鼠标区域覆盖 QML 行(或,自动调整大小的图像+文本)

6
摘要: 我该如何在文本旁边添加一个图标,而不需要硬编码尺寸,并将它们包在MouseArea中…以一种适用于GridLayout的方式?

我创建了一个QML布局,其中有可点击的“按钮”和标签行。按钮是一个图标和文本:

Two rows with two columns; the rightmost column has images and text inline

为了创建按钮,我使用Row,以便两个项目正确粘在一起(没有任何硬编码的尺寸),并具有GridLayout可以使用的自动大小:

GridLayout {
  columns:2; rowSpacing:30

  Text {
    text: audioServer.label
    Layout.alignment: Qt.AlignLeft
  }

  Row {
    spacing:10; Layout.alignment:Qt.AlignRight
    Image { width:29; height:30; y:10; source:"qrc:/rescan.png" }
    Text  { text:"Find Another" }
  }

  Text {
    text: "System uptime "+system.uptime
    Layout.alignment: Qt.AlignLeft
  }

  Row {
    spacing:10; Layout.alignment:Qt.AlignRight
    Image { width:29; height:30; y:10; source:"qrc:/restart.png" }
    Text  { text: "Restart" }
  }
}

我想在每个按钮周围放置一个MouseArea。如果我把它放在行内,像这样...

Row {
  Image { width:29; height:30; y:10; source:"qrc:/rescan.png" }
  Text  { text:"Find Another" }

  MouseArea {
    anchors.fill: parent
    onClicked: rescan()
  }
}

当我在Row中指定左、右、水平居中、填充或居中锚点时,会出现(合理的)错误:QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row. Row will not function. 更重要的是,布局会被破坏(我认为Row得到了零宽度,因此GridLayout使其流到了右侧)。

我无法像这样将MouseArea移动到GridLayout之外...

GridLayout {
  ...
  Row {
    id: rescanButton
    Image { width:29; height:30; y:10; source:"qrc:/rescan.png" }
    Text  { text:"Find Another" }
  }
}
MouseArea {
  anchors.fill: rescanButton
  onClicked: rescan()
}

因为只能将锚定点设置为兄弟或父级元素。

但我无法将 MouseArea 放在 GridLayout 中,因为它会尝试将其布局为一个项目。

如何获得包装按钮的 MouseArea?

对我来说,使用除 Row 之外的容器是可以接受的,但我强烈不希望硬编码任何文本或容器尺寸。


为什么不把MouseArea作为Image的子元素呢? - Filip Hazubski
@FilipHazubski 因为我希望用户能够在图像上的任何位置或与其相关的文本上轻触。 "rescan.png" 只是圆形箭头,但用户也应该能够轻触 "Find Another" 并使其工作。 - Phrogz
你可以将 MouseArea 设为 Image 的子元素,但需要将它的 width 设置为 Image.width + Text.width + gapWidth。我认为你可以定义 ImageTextid 属性,并使其仅在 Row 的范围内可用,以便 MouseArea 可以使用它们。 - Filip Hazubski
@FilipHazubski 您的第一个建议可能有效,但似乎是一种不太优雅的hack。您的第二个建议不能直接使用,因为图像和文本会重叠。 - Phrogz
@FilipHazubski 噢,然而,这个可以工作:MouseArea { width: childrenRect.width; height: childrenRect.height; Row { Image{} Text{} } } 如果您愿意将其发布为答案,我很乐意给您信用。 - Phrogz
显示剩余2条评论
1个回答

10

有了您的帮助,我们得到了这个:

GridLayout {
  ...
  MouseArea {
    onClicked: rescan()
    width:  childrenRect.width
    height: childrenRect.height
    Row {
      Image { width:29; height:30; y:10; source:"qrc:/rescan.png" }
      Text  { text:"Find Another" }
    }
  }
}

@Phrogz 是的,那绝对是更好的方式。 :) - Filip Hazubski
1
只是为了明确起见,GridLayout 可以很容易地成为一个 Rectangle,以防有人看到这个答案并对 GridLayout 产生疑问。这只是来自提问者的问题。 - Boy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接