针对 QML 中的特定组件元素
Posted
技术标签:
【中文标题】针对 QML 中的特定组件元素【英文标题】:Targeting specific component elements in QML 【发布时间】:2018-06-28 17:11:10 【问题描述】:CSS 让 yhour DOM 中特定按钮/元素的悬停效果变得非常容易。我正在尝试为桌面应用程序创建各种登录页面,但我试图避免为我在 main.qml 中创建的每个对象复制粘贴特定状态。
这是我的 main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window
visible: true
width: 640
height: 480
title: qsTr("Hello World")
NavBar
id: mainNavigation
NavButton.qml
Rectangle
id: navButton
height: parent.height
width: parent.width / 3 - 10
color: "orange"
MouseArea
state: "unhovered"
hoverEnabled: true
height: parent.height
width: parent.width
onHoveredChanged:
console.log("hovered")
if(this.state == "hovered")
parent.state = "unhovered"
else
parent.state = "hovered"
// end mouse area
states:
[
State
name: "hovered"
PropertyChanges
target: navButton
width: parent.width
color: "red"
,
State
name: "unhovered"
PropertyChanges
target: navButton
width: parent.width
color: "orange"
]
NavBar.qml
import QtQuick 2.0
import QtQuick.Controls 1.4
Row
id: navigationBar
height: parent.height / 3
width: parent.width
spacing: 15
anchors.centerIn : parent
NavButton
id: selectDevice
NavButton
id: deviceConfig
NavButton
id: deviceInfo
现在,当我将鼠标悬停在其中一个导航按钮上时,它们三个都会扩大尺寸,而我只将鼠标悬停在其中一个上时会扩大并改变颜色。我希望像 CSS 和 javascript 一样,有一种方法可以定位作为悬停事件主题的元素。
我已经尝试过使用 parent 作为状态的目标,但这似乎不起作用。我已经做了一些寻找解决方案的工作,但我没有看到任何明显的东西可以让我完成这个任务。我看到的唯一选择是将状态添加到我的 navBar 文件中的每个单独的 navButton 。
我真的希望不是这样,因为这将是一个简单问题的非常冗长的解决方案。
我真正需要的是一种仅针对发生事件的元素的方法。
【问题讨论】:
【参考方案1】:您可以简单地废弃所有这些状态和诸如此类的东西,对于这种微不足道的场景来说,这些状态确实不需要:
Rectangle
id: navButton
height: parent.height
width: parent.width / 3 - 10
color: ma.containsMouse ? "red" : "orange"
property alias hoverEnabled: ma.hoverEnabled
MouseArea
id: ma
anchors.fill: parent
而且你也为自己节省了一大堆代码。然后只需将hoverEnabled: true
用于您想要悬停的所有按钮。
或者你可以创建一个名为HoverButton.qml
的辅助类型,如果你想避免为每个按钮设置它,它只是一个NavButton hoverEnabled: true
。
我还建议您切换按钮的嵌套顺序:
MouseArea
id: navButton
height: parent.height
width: parent.width / 3 - 10
Rectangle
anchors.fill: parent
color: navButton.containsMouse ? "red" : "orange"
这避免了使用属性别名的需要,为您节省了一个 id
并允许您直接绑定到鼠标区域处理程序挂钩,如果不使用额外的处理程序和信号重定向信号,您无法在原始代码中执行此操作.
最后,我认为将 QML 看成是 html 是没有意义的,QML 不是 HTML,它有自己的使用范例。
【讨论】:
哇,太棒了。我明白你所说的 QML 有它自己的范式的意思,我并没有把它与 HTML 和 CSS 进行比较,因为我想知道我必须缺少什么才能让它看起来更加困难。我从来没有想过你可以用这种方式来做,因为它与 Javascript 中的标准思维有很大的不同。一般来说,我学会了从事件和事件处理程序的角度来思考,所以这是相当不同的!再次感谢您的解决方案 - 正如我所说的那样,我永远不会想到。 如果可以,我想进一步问一下,如何通过过渡期实现这一点?我可能应该一开始就问这个问题,因为我觉得它改变了人们可能采取的方法,但也许我错了!我的意图是“动画”颜色和大小。我已经看到通过状态和转换完成了这一点,但这给我留下了我原来的问题。 QML 有点像 CSS,它是一种类似 HTML 的标记,但它的整体设计理念是不同的。 IMO 管理层做出了一些错误的决定,即在 Web API 之后对某些 API 进行建模,以吸引 Web 开发人员并增加 QML 的采用,这可能会进一步强化技术相似的想法,但事实并非如此。 QML 与 HTML 非常不同,期望相同的工作流程会适得其反。至于动画——只要查一下,有几种方法可以做到。最简单的一种是在属性上安装Behavior
,它会自动为更改设置动画。以上是关于针对 QML 中的特定组件元素的主要内容,如果未能解决你的问题,请参考以下文章
如何从QML中的GridView或ListView获取实例化的委托组件