【问题标题】:QML ReferenceError: <something> is not defined from Js function called from a qml fileQML ReferenceError: <something> is not defined from Js function called from a qml file
【发布时间】:2015-05-05 14:49:18
【问题描述】:

好吧,绝对不知道该怎么做,所以我寻求帮助,我到处寻找,找不到解决方案。 这是一个很长的问题,涉及以下文件:sizeCalc.jsmain.qmlMainForm.ui.qmlVentPrinc.qmlmenuPrincElement.qml,问题是这样的。

在文件MainForm.ui.qml 中有主窗口的结构,main.qml 从那里加载并运行 UI 的逻辑,文件的内容是这样的:

MainForm.ui.qml:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
import "sizeCalc.js" 1.0 as CalcSize

Item {
    id: vent
    width: CalcSize.vW; height: CalcSize.vH
    property alias itemCont: itemCont
    property alias vent: vent
    property alias rootBarraUp: rootBarraUp

    Image {
        id: imgBgrnd
        source: "imgSources/background.jpg"
        sourceSize.height: parent.height
        fillMode: Image.PreserveAspectFit
        anchors.centerIn: parent
    }
    ColumnLayout {
        id: layoutPrinc
        anchors.fill: parent
        Rectangle {
            id: barraUpRef
            height: CalcSize.barrasPrnc; width: parent.width
            anchors.top: parent.top; color: "transparent"
            anchors.horizontalCenter: parent.horizontalCenter
        }
        Item {
            id: rootBarraUp; z:20
            width: parent.width; anchors.top: barraUpRef.top
            anchors.horizontalCenter: barraUpRef.horizontalCenter
        }
        Item {
            id:itemContGen
            anchors.top: barraUpRef.bottom; anchors.bottom: barraDown.top
            width: vent.width; anchors.horizontalCenter: parent.horizontalCenter
            Item {
                id: itemCont
                anchors.centerIn: parent
                height: CalcSize.espTrbHei; width: CalcSize.espTrbWid
            }
        }
        Rectangle {
            id: barraDown
            height: CalcSize.barrasPrnc; width: parent.width
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 0
            color: "white"; opacity: 0.3
        }
    }
    states: [
        State {
            name: "directorio"
            PropertyChanges {
                target: barraDown
                anchors.bottomMargin: -(height)
            }
        }
    ]
}

main.qml:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import "sizeCalc.js" 1.0 as CalcSize

ApplicationWindow {
    title: qsTr("Hello World")
    width: 480
    height: 640
    visible: true
    MainForm {
        id: mainForm; anchors.fill: parent
        function chVent(arg){
            CalcSize.funcCambVent(arg)
        }
        itemCont.children: StackView {
            id: stackviewPrinc; anchors.fill: parent
            anchors.margins: CalcSize.espTrbDirecBordUp
            initialItem: compPrinc

            Component {
                id: compPrinc
                Loader {
                    id: loaderPrinc
                    source: "VentPrinc.qml"
                    Connections {
                        target: loaderPrinc.item.dirBoton
                        onClicked: CalcSize.funcCambVent(1)
                    }
                }
            }
            Component {
                id: compDir
                Loader {
                    id: loaderDir
                    source: "Directorio.qml"
                }
            }
            Component {
                id: comp3
                Loader {
                    id: loaderComp3
                }
            }
            Component {
                id: comp4
                Loader {
                    id: loaderComp4
                }
            }

            delegate: StackViewDelegate {
                function transitionFinished(properties){
                    properties.exitItem.opacity = 1
                }
                pushTransition: StackViewTransition {
                    PropertyAnimation {
                        target: enterItem
                        property: "opacity"
                        from: 0; to: 1
                    }
                    PropertyAnimation {
                        target: exitItem
                        property: "opacity"
                        from: 1; to: 0
                    }
                }
            }
        }
        rootBarraUp.children: Loader {
            id: barraUpLoader
            anchors.top: parent.top
            anchors.horizontalCenter: parent.horizontalCenter
            source: "menuPrincElement.qml"
            transitions: Transition {
                NumberAnimation {
                    properties: "height, width"
                    easing.type: Easing.InOutQuad
                }
            }
        }

        vent.transitions: [
            Transition {
                NumberAnimation {
                    target: barraDown; duration: 500
                    property: "anchors.bottomMargin"
                    easing.type: Easing.Linear
                }
            }
        ]
    }
}

VentPrinc.qml 是从StackView 中的main.qml 加载的,这是文件的内容:

import QtQuick 2.4
import QtQuick.Layouts 1.1
import "sizeCalc.js" 1.0 as CalcSize

Item {
    id: contenidoGen
    anchors.top: parent.bottom; anchors.bottom: parent.top
    anchors.horizontalCenter: parent.horizontalCenter
    width: CalcSize.espTrbWid
    property alias dirBoton: mouseAreaBotonDirPrinc
    property alias turBoton: mouseAreaBotonTurPrinc
    RowLayout {
        id: layoutBotonesPrinc
        anchors.centerIn: parent
        Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter

        Item {
            id: botonPrincDirectorio
            height: CalcSize.tamBotonesPrinc; width: height
            Image {
                id: imgBotonPrincDirectorio
                source: "imgSources/botones/directorioBotonPrinc.png"
                sourceSize.height: parent.height
                fillMode: Image.PreserveAspectFit
                anchors.centerIn: parent
            }
            MouseArea {
                id: mouseAreaBotonDirPrinc
                anchors.fill: parent
                /*onClicked: {
                    mainForm.chVent(1)
                }*/
            }
        }
        Item {
            id: botonPrincTurista
            height: CalcSize.tamBotonesPrinc; width: height
            Image {
                id: imgBotonPrincTurista
                source: "imgSources/botones/turistaBotonPrinc.png"
                sourceSize.height: parent.height
                fillMode: Image.PreserveAspectFit
                anchors.centerIn: parent
            }
            MouseArea {
                id: mouseAreaBotonTurPrinc
                anchors.fill: parent
            }
        }
    }
}

menuPrincElement.qml 是从 loadermain.qml 加载的(此元素是 UI 的顶部栏),这是文件的内容:

import QtQuick 2.4
import QtQuick.Layouts 1.1
import "sizeCalc.js" 1.0 as CalcSize
Rectangle {
    property alias barraSup: barraUP
    id: barraUP
    height: CalcSize.barrasPrnc; width: CalcSize.vW
    color: "transparent"
    FontLoader { id: fontGent; source: "Aaargh.ttf" }
    function chTitulo(arg){
        switch(arg){
        case 0: tituloItemText.state = "stPrinc"; break;
        case 1: tituloItemText.state = "stDir"; break;
        case 2: tituloItemText.state = "stTur"; break;
        case 3: tituloItemText.state = "stConf"; break;
        }
    }

    Rectangle {
        id: backgroundMenuList; color: "white"; opacity: 0.0
        anchors.fill: parent
    }
    Item {
        id: contBarrUp
        height: CalcSize.barrasPrnc; width: parent.width
        anchors.top: parent.top
        anchors.horizontalCenter: parent.horizontalCenter
        Rectangle {
            id: backgroundBarrUp; color: "white"; opacity: 0.3
            anchors.fill: parent
        }
        Item {
            id: menuItem
            width: CalcSize.tamBotonMenuPrinc
            height: CalcSize.tamBotonMenuPrinc
            anchors.verticalCenter: parent.verticalCenter
            anchors.left: parent.left
            Image {
                id: menuItemImg
                source: "imgSources/botones/botonMenuPrinc.png"
                sourceSize.height: parent.height
                fillMode: Image.PreserveAspectFit
                anchors.centerIn: parent
            }
            MouseArea {
                id: menuItemMouseArea; anchors.fill: menuItem
                onClicked: {
                    if(barraUP.state == ""){
                        barraUP.state = "menuOn"
                    }else{
                        barraUP.state = ""
                    }
                }
            }
        }
        Text {
            id: tituloItemText; color: "white"
            //text: CalcSize.textoTitulo;
            anchors.centerIn: parent
            verticalAlignment: Text.AlignVCenter
            font { bold: true; pointSize: 16; family: fontGent.name }
            state: "stPrinc"
            states: [
                State {
                    name: "stPrinc"
                    PropertyChanges { target: tituloItemText; text: "App Turista" }
                },
                State {
                    name: "stDir"
                    PropertyChanges { target: tituloItemText; text: "Modo Directorio" }
                },
                State {
                    name: "stTur"
                    PropertyChanges { target: tituloItemText; text: "Modo Turista" }
                },
                State {
                    name: "stConf"
                    PropertyChanges { target: tituloItemText; text: "Configuración" }
                }
            ]
            Transition {
                PropertyAnimation {
                    target: tituloItemText
                    duration: 500; easing.type: Easing.InOutQuad
                }
            }
        }
    }
    Item {
        id: contOpcMenuGen; width: parent.width
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: contBarrUp.bottom; anchors.margins: 10
        anchors.bottom: barraUP.bottom; opacity: 0
        ListView {
            id: listaContMenuGen; anchors.fill: parent
            delegate: delegateElemMenuGen
            model: modelElemMenuGen
            spacing: CalcSize.tamBordeElemIntLista3
        }
    }
    Component {
        id: delegateElemMenuGen
        Rectangle {
            id: recPrinc; color: "transparent"
            anchors.margins: CalcSize.tamBordeElemIntLista2
            anchors.horizontalCenter: parent.horizontalCenter
            height: CalcSize.tamElemMenuPrincH
            width: CalcSize.espTrbWid
            Rectangle {
                id: backgroundRecPrinc; color: "white"; opacity: 0.8
                radius: CalcSize.tamBordeElemIntLista3
                anchors.fill: recPrinc
            }
            MouseArea {
                id: mouseAreaDelegateItem; anchors.fill: parent
                onClicked: {
                    CalcSize.funcCambVent(model.accion)
                    barraUP.state = ""
                }
            }
            Text {
                id: textoElem; color: "black"; text: model.titulo
                anchors.centerIn: parent
                font { bold: true; family: fontGent.name; pointSize: 12 }
            }
        }
    }
    ListModel {
        id: modelElemMenuGen
        ListElement { titulo: "Regresar al Inicio"; accion: 0 }
        ListElement { titulo: "Modo Directorio";    accion: 1 }
        ListElement { titulo: "Modo Turista";       accion: 2 }
        ListElement { titulo: "Configuración";      accion: 3 }
    }

    states: [
        State {
            name: "menuOn"
            PropertyChanges {
                target: tituloItemText; color: "#5a5a5a"
            }

            PropertyChanges {
                target: barraUP; height: CalcSize.tamElemMenuPrincExpand
            }
            PropertyChanges {
                target: contOpcMenuGen; opacity: 1
            }
            PropertyChanges {
                target: backgroundBarrUp; opacity: 0.75
            }
            PropertyChanges {
                target: backgroundMenuList; opacity: 0.7
            }
        }
    ]
    transitions: [
        Transition {
            from: ""; to: "menuOn"
            ParallelAnimation {
                NumberAnimation {
                    target: barraUP; properties: "height"
                    duration: 500; easing.type: Easing.InOutQuad
                }
                NumberAnimation {
                    target: backgroundBarrUp; property: "opacity"
                    duration: 500; easing.type: Easing.InOutQuad
                }
                ColorAnimation {
                    target: tituloItemText; duration: 500
                }
            }
            SequentialAnimation {
                NumberAnimation {
                    target: backgroundMenuList; property: "opacity"
                    duration: 250; easing.type: Easing.InOutQuad
                }
                NumberAnimation {
                    target: contOpcMenuGen; property: "opacity"
                    duration: 250; easing.type: Easing.InOutQuad
                }
            }
        },
        Transition {
            from: "menuOn"; to: ""
            SequentialAnimation {
                NumberAnimation {
                    target: contOpcMenuGen; property: "opacity"
                    duration: 250; easing.type: Easing.InOutQuad
                }
                NumberAnimation {
                    target: backgroundMenuList; property: "opacity"
                    duration: 250; easing.type: Easing.InOutQuad
                }
            }
            ParallelAnimation {
                NumberAnimation {
                    target: barraUP; properties: "height"
                    duration: 500; easing.type: Easing.InOutQuad
                }
                NumberAnimation {
                    targets: backgroundBarrUp; property: "opacity"
                    duration: 500; easing.type: Easing.InOutQuad
                }
                ColorAnimation {
                    target: tituloItemText; duration: 500
                }
            }
        }
    ]
}

最后,sezeCalc.js 文件只是一个函数和变量的集合,用于根据窗口大小计算 UI 元素的大小,这是该文件的重要内容:

function funcCambVent(arg){
    switch(arg){
    case 0:
        barraSup.state = ""
        mainForm.state = ""
        barraSup.chTitulo(0)
        stackviewPrinc.push(compPrinc)
        break
    case 1:
        barraSup.state = ""
        mainForm.state = "directorio"
        barraSup.chTitulo(1)
        stackviewPrinc.push(compDir)
        break
    case 2:
        barraSup.state = ""
        mainForm.state = ""
        barraSup.chTitulo(2)
        stackviewPrinc.push(comp3)
        break
    case 3:
        barraSup.state = ""
        mainForm.state = ""
        barraSup.chTitulo(3)
        stackviewPrinc.push(comp4)
        break
    }
}

问题是这样的,VentPrinc.qmlmenuPrincElement.qml 都有一个MouseArea 来调用sizeCalc.js 中的一个函数,它改变了StackView 的当前“页面”,以便转到另一个“窗口”界面,同时保留各种 UI 元素,如果从 menuPrincElement.qml 调用该函数,但要从 VentPrinc.qml 调用得到错误 "qrc: /sizeCalc.js: 16: ReferenceError: barraSup is not defined",则一切正常,我已尽我所能改变调用函数的方式但错误仅在从VentPrinc.qml 调用时仍然存在,尝试连接来自VentPrinc.qml 的信号以调用main.qml 中的函数,并且该函数调用函数sizeCalc.js 还执行来自位于的加载器VentPrinc.qml 的连接StackViewmain.qml 也我使用了property alias 的来自sizeCalc.js 的受影响项目...好吧我不知道还有什么尝试总是得到相同的错误"ReferenceError: barraSup is not defined" 这个错误只在信号到来时发生来自VentPrinc.qml,如果有人知道我做错了什么,我会非常感谢,非常感谢您的关注,希望您的回答。

PS:我为语法错误道歉,但这是谷歌翻译,我的英语语法不太好。

PD2:我留下了一些我尝试过的其他解决方案的注释或未使用的代码部分。

【问题讨论】:

  • 就我个人而言,这对我来说实在是太多了。您应该尝试将其缩小到问题的最小再现。拿走一些东西(一段代码,然后是一个文件等),看看它是否仍然可以重现,直到你只剩下几个文件。

标签: javascript qml loader stackview


【解决方案1】:

我找到了解决方案,老实说,我不知道为什么这个解决方案有效,但它有效,如果有人可以解释这将对遇到此类问题的人有所帮助。 sizeCalc.js文件中的功能变化:

function funcCambVent(arg){
    switch(arg){
    case 0:
        barraUpLoader.item.state = ""
        mainForm.state = ""
        barraUpLoader.item.chTitulo(0)
        stackviewPrinc.push(compPrinc)
        break
    case 1:
        barraUpLoader.item.state = ""
        mainForm.state = "directorio"
        barraUpLoader.item.chTitulo(1)
        stackviewPrinc.push(compDir)
        break
    case 2:
        barraUpLoader.item.state = ""
        mainForm.state = ""
        barraUpLoader.item.chTitulo(2)
        stackviewPrinc.push(comp3)
        break
    case 3:
        barraUpLoader.item.state = ""
        mainForm.state = ""
        barraUpLoader.item.chTitulo(3)
        stackviewPrinc.push(comp4)
        break
    }
}

并且VentPrinc.qml根元素而不是ItemI被Rectangle替换并将文件重命名为ventPrinc.qml,在此文件中不再需要以任何方式连接sizeCalc.js内的特殊功能,只需直接调用函数,这个文件的最终版本:

import QtQuick 2.4
import QtQuick.Layouts 1.1
import "sizeCalc.js" 1.0 as CalcSize

Rectangle {
    id: contenidoGen; color: "transparent"
    anchors.top: parent.bottom; anchors.bottom: parent.top
    anchors.horizontalCenter: parent.horizontalCenter
    width: CalcSize.espTrbWid
    property alias dirBoton: mouseAreaBotonDirPrinc
    property alias turBoton: mouseAreaBotonTurPrinc
    RowLayout {
        id: layoutBotonesPrinc
        anchors.centerIn: parent
        Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter

        Item {
            id: botonPrincDirectorio
            height: CalcSize.tamBotonesPrinc; width: height
            Image {
                id: imgBotonPrincDirectorio
                source: "imgSources/botones/directorioBotonPrinc.png"
                sourceSize.height: parent.height
                fillMode: Image.PreserveAspectFit
                anchors.centerIn: parent
            }
            MouseArea {
                id: mouseAreaBotonDirPrinc
                anchors.fill: parent
                onClicked: CalcSize.funcCambVent(1)
            }
        }
        Item {
            id: botonPrincTurista
            height: CalcSize.tamBotonesPrinc; width: height
            Image {
                id: imgBotonPrincTurista
                source: "imgSources/botones/turistaBotonPrinc.png"
                sourceSize.height: parent.height
                fillMode: Image.PreserveAspectFit
                anchors.centerIn: parent
            }
            MouseArea {
                id: mouseAreaBotonTurPrinc
                anchors.fill: parent
            }
        }
    }
}

除此之外,没有必要使用property alias dirBoton: mouseAreaBotonDirPrinc

main.qml 中的最后一个 StackView 是:

itemCont.children: StackView {
            id: stackviewPrinc; anchors.fill: parent
            anchors.margins: CalcSize.espTrbDirecBordUp
            initialItem: compPrinc

            Component {
                id: compPrinc
                Loader { id: loaderPrinc; source: "ventPrinc.qml" }
            }
            Component {
                id: compDir
                Loader { id: loaderDir; source: "ventDir.qml" }
            }
            Component {
                id: comp3
                Loader { id: loaderTur }
            }
            Component {
                id: comp4
                Loader { id: loaderConf }
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 2015-01-29
    相关资源
    最近更新 更多