QML ReferenceError: <что-то> не определено из функции Js, вызываемой из файла qml
Хорошо, точно не знаю, что делать, поэтому я прошу о помощи, я искал везде и не могу найти решение. В этот длинный вопрос были включены следующие файлы: sizeCalc.js
, main.qml
, MainForm.ui.qml
, VentPrinc.qml
а также menuPrincElement.qml
проблема в этом.
Внутри файла MainForm.ui.qml
имеют структуру главного окна, которое main.qml
загрузите и запустите оттуда логику пользовательского интерфейса, содержимое файлов выглядит так:
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
загружается из loader
от main.qml
(этот элемент является верхней панелью пользовательского интерфейса), и это содержимое файла:
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
file - это просто набор функций и переменных для расчета размера элементов пользовательского интерфейса в зависимости от размера окна, и это важное содержимое этого файла:
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.qml
а также menuPrincElement.qml
иметь MouseArea
вызвать функцию внутри sizeCalc.js
которые меняют текущую "страницу" StackView
это для того, чтобы перейти к другому "оконному" интерфейсу при сохранении различных элементов пользовательского интерфейса, все прекрасно работает, если функция вызывается из menuPrincElement.qml
но быть вызванным из VentPrinc.qml
получить ошибку "qrc: /sizeCalc.js: 16: ReferenceError: barraSup is not defined"
Я перепробовал все, что мог, чтобы изменить способ вызова функции, но ошибка сохраняется только при вызове из VentPrinc.qml
попробуйте подключить сигнал от VentPrinc.qml
вызвать функцию в main.qml
и что эта функция вызывает функцию sizeCalc.js
также выполнить подключения от загрузчика VentPrinc.qml
расположенный в StackView
из main.qml
также я использовал property alias
из затронутых предметов из sizeCalc.js
... ну я не знаю, что еще пытаются всегда получать одну и ту же ошибку "ReferenceError: barraSup is not defined"
Эта ошибка происходит только тогда, когда сигнал приходит от VentPrinc.qml
Пожалуйста, если кто-то знает, что я делаю неправильно, я буду очень признателен, большое спасибо за внимание и надеюсь на ваши ответы.
PS: Я прошу прощения за грамматические ошибки, но это перевод Google, моя грамматика на английском языке не так хороша.
PD2: Я оставил некоторые части кода закомментированными или не использованными в других решениях, которые я пробовал.
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
корневой элемент вместо 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
,
Финал StackView
в main.qml
является:
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 }
}
}