Evan Krause
Evan Krause

Reputation: 187

How to position one label at the end of another label and center both of them

Basically I want to display a text telling the user if a switch is turned on or off. The words "on" and "off" have a small background associated with them so I thought maybe making two labels would work. Now I have an issue where I'm hard coding the position of the second label, and it doesn't look clean because both of them are not centered. Here is the code:

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.0

Window {
  visible: true
  width: 400
  height: 400

  property bool switchOn: false

  Rectangle {
      color: '#D3D3D3'
      anchors.fill: parent

      Label {
          id: sentence
          text: qsTr("The switch is currently turned ")
          color: 'black'
          width: parent.width
          wrapMode: Text.Wrap
          font.pixelSize: 40
          anchors.top: parent.top
          Label {
              id: endText
              text: switchOn ? qsTr(" off ") : qsTr(" on ")
              font.pixelSize: 40
              color: "white"
              anchors {
                  top: parent.top
                  left: parent.left
                  topMargin: 50
                  leftMargin: 310
              }

              // @disable-check M16
              background: Rectangle {
                  color: switchOn ? "grey" : "red"
                  radius: 8
              }
          }
      }

      Switch {
          id: switch1
          anchors.horizontalCenter: parent.horizontalCenter
          anchors.top: parent.top
          anchors.topMargin: 150
          text: qsTr("Switch")
          onToggled: switchOn = !switchOn
      }
  }
}

How can I have that sentence appear as one sentence and center it within a parent object?

EDIT: Here I can get them in a row, but if my sentence ends on the second row and my first row is longer than the first, the ending text is placed way further than it needs to be:

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.0

Window {
  visible: true
  width: 400
  height: 400

  property bool switchOn: false

  Rectangle {
      color: '#D3D3D3'
      anchors.fill: parent

      Row {
          anchors.horizontalCenter: parent.horizontalCenter

          Label {
              id: sentence
              text: qsTr("The switch is currently ")
              color: 'black'
              width: 300
              wrapMode: Text.Wrap
              font.pixelSize: 40
              anchors.top: parent.top
          }
          Label {
              id: endText
              text: switchOn ? qsTr(" off ") : qsTr(" on ")
              font.pixelSize: 40
              color: "white"
              anchors.top: sentence.top
              anchors.topMargin: 45
              // @disable-check M16
              background: Rectangle {
                  color: switchOn ? "grey" : "red"
                  radius: 8
              }
          }
      }

      Switch {
          id: switch1
          anchors.horizontalCenter: parent.horizontalCenter
          anchors.top: parent.top
          anchors.topMargin: 150
          text: qsTr("Switch")
          onToggled: switchOn = !switchOn
      }
  }
}

Upvotes: 1

Views: 677

Answers (2)

GrecKo
GrecKo

Reputation: 7150

You can do that by using the lineLaidOut signal of the Label. It gives you information about each line's geometry (you can also modify them if needed):

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.0

Window {
    id: root
    visible: true
    width: 400
    height: 400

    property bool switchOn: false

    Rectangle {
        color: '#D3D3D3'
        anchors.fill: parent

        Label {
            id: sentence
            text: qsTr("The switch is currently ")
            color: 'black'
            anchors.horizontalCenter: parent.horizontalCenter
            width: 300
            wrapMode: Text.Wrap
            font.pixelSize: 40
            anchors.top: parent.top
            property real lastLineY
            property real lastLineWidth
            onLineLaidOut: line => {
                               if (line.isLast) {
                                   lastLineY = line.y;
                                   lastLineWidth = line.implicitWidth
                               }
                           }
            Label {
                id: endText
                text: root.switchOn ? qsTr(" off ") : qsTr(" on ")
                font.pixelSize: 40
                color: "white"
                x: sentence.lastLineWidth
                y: sentence.lastLineY
                background: Rectangle {
                    color: root.switchOn ? "grey" : "red"
                    radius: 8
                }
            }
        }

        Switch {
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.top: parent.top
            anchors.topMargin: 150
            text: qsTr("Switch")
            onToggled: root.switchOn = !root.switchOn
        }
    }
}

Upvotes: 3

JarMan
JarMan

Reputation: 8277

You can put the Labels within a Row, and horizontally center the Row.

Rectangle {
    color: '#D3D3D3'
    anchors.fill: parent

    Row {
        anchors.horizontalCenter: parent.horizontalCenter
     
        Label {
            id: sentence
            ...
        }
        Label {
            id: endText
            anchors.top: sentence.top
            ...
        }
    }
}

Upvotes: 1

Related Questions