Search code examples
qmlpyqt6

Want to connect QML types across the QML files in PyQt6


This is a simple example of what I want to do.

// main.qml

import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Controls.Material

ApplicationWindow {
  visible: true
  width: 640
  height: 480
  title: "Example App"

  Material.theme: Material.Dark

  MyLabel {
    id: idMyLabel
    anchors.centerIn: parent
  }

  MyButton {
    anchors.top: idMyLabel.bottom
    anchors.horizontalCenter: parent.horizontalCenter
  }
}
// MyLabel.qml

import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Controls.Material

RowLayout {
  spacing: 40

  Label {
    id: idInnerLabel1
    text: "Label 1"
  }

  Label {
    id: idInnerLabel2
    text: "Label 2"
  }

  Label {
    id: idInnerLabel3
    text: "Label 3"
  }
}
// MyButton.qml

import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Controls.Material

Page {
  Button {
    text: "Change"
    onClicked: idInnerLabel2.text = "Changed"
  }
}

But, I got an error when I run this example.

ReferenceError: idInnerLabel2 is not defined

I wanted to communicate between nested QML files. Putting them together in one file worked fine. So I was confused and I couldn't understand its inner working.

How can I resolve this issue?


Solution

  • Since both MyButton and MyLabel appear in main.qml the simplest solution would be to create a property in main.qml that both can access.

    import QtQuick
    import QtQuick.Controls
    
    Page {
      property string txt1: "Label 1"
      property string txt2: "Label 2"
      property string txt3: "Label 3"
      MyLabel {
        id: idMyLabel
        anchors.centerIn: parent
      }
    
      MyButton {
        anchors.top: idMyLabel.bottom
        anchors.horizontalCenter: parent.horizontalCenter
      }
    }
    
    // MyLabel.qml
    
    import QtQuick
    import QtQuick.Layouts
    import QtQuick.Controls
    import QtQuick.Controls.Material
    
    RowLayout {
      spacing: 40
    
      Label {
        text: txt1
      }
    
      Label {
        text: txt2
      }
    
      Label {
        text: txt3
      }
    }
    
    // MyButton.qml
    
    import QtQuick
    import QtQuick.Layouts
    import QtQuick.Controls
    import QtQuick.Controls.Material
    
    Page {
      Button {
        text: "Change"
        onClicked: txt2 = "Changed"
      }
    }
    

    You can Try it Online!