QML ReferenceError: <something> is not defined from Js function called from a qml file

QML ReferenceError: <something> is not defined from Js function called from a qml file

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

在文件 MainForm.ui.qml 中有 main.qml 加载的主要 window 结构和 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是从main.qml内的一个StackView加载的,这是文件的内容:

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 是从 main.qmlloader 加载的(这个元素是 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 文件只是函数和变量的集合,用于根据 window 的大小计算 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 中的一个函数,它改变 "page" 的当前 StackView 这是为了在保留各种 UI 元素的同时转到另一个 "window" 界面,如果从 menuPrincElement.qml 调用该函数但从 [=18 调用该函数,则一切正常=] 得到错误 "qrc: /sizeCalc.js: 16: ReferenceError: barraSup is not defined" 我已尽我所能改变调用函数的方式,但错误仅在从 VentPrinc.qml 调用时仍然存在,请尝试连接来自 VentPrinc.qml 的信号在 main.qml 中调用一个函数并且这个函数调用函数 sizeCalc.js 也执行来自位于 main.qmlStackView 中的加载器 VentPrinc.qml 的连接我也使用过property alias 受影响的项目来自 sizeCalc.js...好吧,我不知道还有什么尝试总是得到相同的错误 "ReferenceError: barraSup is not defined" 只有当信号来自 [=18] 时才会发生此错误=],如果有人知道我做错了什么,我将不胜感激,非常感谢您的关注,我希望得到您的答复。[=4 8=]

PS: 对于语法错误,我深表歉意,但这是google翻译,我的英语语法不太好。

PD2:我对我尝试过的其他解决方案的部分代码进行了注释或未使用。

我找到了解决方案,老实说我不知道​​为什么这个解决方案有效,但它有效,如果有人能解释这对遇到此类问题的人会有帮助。 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根元素而不是Item我被替换为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 }
            }
        }