【问题标题】:Targeting specific component elements in QML针对 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 。

我真的希望不是这样,因为这将是一个简单问题的非常冗长的解决方案。

我真正需要的是一种仅针对发生事件的元素的方法。

【问题讨论】:

    标签: javascript qt user-interface qml


    【解决方案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,它会自动为更改设置动画。
    猜你喜欢
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 2018-07-22
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    • 2021-07-18
    相关资源
    最近更新 更多