属性别名自引用?这个 QML 代码在做啥?

Posted

技术标签:

【中文标题】属性别名自引用?这个 QML 代码在做啥?【英文标题】:Property alias self reference? What is this QML code doing?属性别名自引用?这个 QML 代码在做什么? 【发布时间】:2015-10-08 10:26:00 【问题描述】:

所以我正在尝试让 maliit 框架和键盘插件在 Windows 上运行。原始来源可以在here 和here 找到。

我有很多不同的问题,但我的问题是关于在以下 QML 代码中使用 QML 属性 alias。在我看来,titlealias 指的是keyboard_title.text,但同时keyboard_titletext 设置为aliastitle?对我来说似乎是循环的。这里到底发生了什么?

/*
 * This file is part of Maliit plugins
 *
 * Copyright (C) 2012-2013 Canonical Ltd
 *
 * Contact: maliit-discuss@lists.maliit.org
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list
 * of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 * Neither the name of Nokia Corporation nor the names of its contributors may be
 * used to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

import QtQuick 2.5

Item 
    property alias layout: main.model
    property variant event_handler
    property bool area_enabled // MouseArea has no id property so we cannot alias its enabled property.
    property alias title: keyboard_title.text

    width: layout.width
    height: layout.height
    visible: layout.visible

    Connections 
        target: layout
        onTitleChanged: 
            console.debug("title:" + layout.title)
            title_timeout.start()
        
    

    BorderImage 
        id: background
        anchors.fill: parent
        source: layout.background

        border.left: layout.background_borders.x
        border.top: layout.background_borders.y
        border.right: layout.background_borders.width
        border.bottom: layout.background_borders.height
    

    Repeater 
        id: main
        model: layout
        anchors.fill: parent

        Item 
            x: key_reactive_area.x
            y: key_reactive_area.y
            width: key_reactive_area.width
            height: key_reactive_area.height

            BorderImage 
                x: key_rectangle.x
                y: key_rectangle.y
                width: key_rectangle.width
                height: key_rectangle.height

                border.left: key_background_borders.x
                border.top: key_background_borders.y
                border.right: key_background_borders.width
                border.bottom: key_background_borders.height

                source: key_background

                Text 
                    anchors.fill: parent
                    text: key_text
                    font.family: key_font
                    font.pointSize: key_font_size
                    color: key_font_color
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                    visible: (key_text.length != 0)
                

                Image 
                    anchors.centerIn: parent
                    source: key_icon
                    visible: (key_icon.length != 0)
                
            

            MouseArea 
                property real start_x
                property real start_y

                Timer 
                    id: gesture_timeout
                    interval: 500
                

                enabled: area_enabled
                anchors.fill: parent
                hoverEnabled: true

                onEntered: event_handler.onEntered(index)
                onExited: event_handler.onExited(index)

                onPressed: 
                    start_x = mouse.x
                    start_y = mouse.y
                    gesture_timeout.start()

                    event_handler.onPressed(index)
                

                onReleased: event_handler.onReleased(index)
                onPressAndHold: event_handler.onPressAndHold(index)

                // TODO: Move logic into EventHandler because gestures should depend on style?
                // Hide keyboard on flick-down gesture (but only if there is an event_handler)
                // or switch to left/right layout:
                onPositionChanged: 
                    if (event_handler
                        && gesture_timeout.running
                        && (mouse.y - start_y > (layout.height * 0.3))) 
                        maliit.hide()
                     else if (event_handler
                               && gesture_timeout.running
                               && (mouse.x - start_x > (layout.width * 0.2))) 
                        maliit.selectLeftLayout()
                     else if (event_handler
                               && gesture_timeout.running
                               && (start_x - mouse.x > (layout.width * 0.2))) 
                        maliit.selectRightLayout()
                    
                
            
        
    

    // Keyboard title rendering
    // TODO: Make separate component?
    Item 
        anchors.centerIn: parent
        opacity: title_timeout.running ? 1.0 : 0.0

        Behavior on opacity 
            PropertyAnimation 
                duration: 300
                easing.type: Easing.InOutQuad
            
        

        Timer 
            id: title_timeout
            interval: 1000
        

        // TODO: Make title background part of styling profile.
        BorderImage 
            anchors.centerIn: parent

            // Manual padding of text:
            width: keyboard_title.width * 1.2
            height: keyboard_title.height * 1.2

            //anchors.fill: keyboard_title
            source: layout.background
            z: 1000 // Move behind Text element but in front of rest.

            border.left: layout.background_borders.x
            border.top: layout.background_borders.y
            border.right: layout.background_borders.width
            border.bottom: layout.background_borders.height
        

        Text 
            id: keyboard_title
            anchors.centerIn: parent

            text: title;
            z: 1001

            // TODO: Make title font part of styling profile.
            font.pointSize: 48
            color: "white"
        
    

【问题讨论】:

【参考方案1】:

它用于将属性暴露给另一个 QML:

Keyboard 
    layout: maliit_layout
    event_handler: maliit_event_handler
    area_enabled: !maliit_extended_layout.visible
    title: maliit_layout.title

这允许在另一个文件中与keyboard_title.text 交互,并创建可读的自定义组件。

是的,有一个循环,如果你设置title,你设置keyboard_title.text,如果你设置keyboard_title.text,你设置标题。完全没问题。

注意: 我在 C++ 代码中经常使用别名。它允许更改子项的属性,而无需找到它,这可能是真正的捷径。

【讨论】:

当然可以,但实际上没用。当您设置title 时,您正在设置keyboard_title.text,反之亦然。由于文件很长,因此可能会强调相关性。评论就足够了。 我认为这只是一种干净的方式。 所以在这种情况下 text: title;行为与文本相同:; ,也就是说它没有初始值?但是有没有让读者(fx me)清楚它是通过标题属性别名设置的? 没错。当调用组件时,title 将设置在更高级别。请注意,我在答案中输入的代码来自 malit github repo 中同一文件夹中的文件 maliit-keyboard.qml,此代码将标题设置为 maliit_layout.title。所以实际上它直接将keyboard_title.text 设置为maliit_layout.title 如果没有keyboard_title 中的text: title; 行,您的示例也可以正常工作。 OP 询问的是该行的有用性,而不是别名。【参考方案2】:

在我看来,代码最初是这样的:

import QtQuick 2.5

Item 
    property alias layout: main.model
    property variant event_handler
    property bool area_enabled 
    property string title
    ...

    Item
    
        ...
        Text 
            id: keyboard_title
            anchors.centerIn: parent

            text: title;
            ...
        
    

然后写这篇文章的人想“嘿,使用别名而不是创建新的字符串属性可能是个好主意!”并继续编写当前代码,但忘记删除text: title这一行。

【讨论】:

以上是关于属性别名自引用?这个 QML 代码在做啥?的主要内容,如果未能解决你的问题,请参考以下文章

这行 Java 代码在做啥?

这行 Ruby 代码在做啥? [复制]

这段代码在做啥[重复]

这段代码在做啥?

Opencv 代码 - 有人可以帮我理解代码在做啥吗

Qml属性vs别名