konrad
konrad

Reputation: 51

Qt5 QtQuick 2.0 (Qt Quick Application) switching views (qml files) in one window

In traditional Qt (QWidget) I have one QMainWindow and some dynamically created QWidgets with the content and I change them that one was seen in main windows. What are the ways of achieving when I have couple qml files and I wants to be able to switch between them when eg clicking a button.

Upvotes: 5

Views: 2564

Answers (2)

Theo FORTIN
Theo FORTIN

Reputation: 1

I would use a simple Loader, with a button that when is clicked, changes the source file of the Loader. Like so :

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

Window {
    id: root

    Rectangle {
        id: page_main
        color: "#202020"
        anchors.fill : parent
        Button {
            id: button_page_1
            width: 105
            text: qsTr("Page 1")
            anchors {
                left: parent.left
                top: parent.top
                leftMargin: 6
                topMargin: 0
            }
            checkable: true
            onClicked: {
               if (loader_main.source == "/page_1.qml") {
                   loader_main.source = ""
               } else {
                   loader_main.source = "/page_1.qml"
                   button_page_2.checked = false
                   button_page_3.checked = false
               }
           }
        }
        Button {
            id: button_page_2
            width: 105
            text: qsTr("Page 2")
            anchors {
                left: button_auto.right
                top: parent.top
                leftMargin: 6
                topMargin: 0
            }
            checkable: true
            onClicked: {
               if (loader_main.source == "/page_2.qml") {
                   loader_main.source = ""
               } else {
                   loader_main.source = "/page_2.qml"
                   button_page_1.checked = false
                   button_page_3.checked = false
               }
           }
        }
        Button {
            id: button_page_3
            width: 105
            text: qsTr("Page 3")
            anchors {
                left: button_manual.right
                top: parent.top
                leftMargin: 6
                topMargin: 0
            }
            checkable: true
            onClicked: {
               if (loader_main.source == "/page_page_3.qml") {
                   loader_main.source = ""
               } else {
                   loader_main.source = "/page_page_3.qml"
                   button_page_1.checked = false
                   button_page_2.checked = false
               }
           }
        }
    }
    Loader {
        id: loader_main
        y: 60
        visible: true
        anchors {
            top: parent.top
            bottom: parent.bottom
            right: parent.right
            left: parent.left
            topMargin: 48
            bottomMargin: 0
            leftMargin: 0
            rightMargin: 0
        }
    }
}

Upvotes: 0

Andrey  Yankovich
Andrey Yankovich

Reputation: 939

There are at least 3 options for solving this problem:

  1. You can use the ready for this purpose component StackView. The point is that you will create 2 components at once and you'll be able to change them by clicking on the button.

Example:

import QtQuick 2.12
import QtQuick.Controls 2.5

ApplicationWindow {
    id: window
    visible: true
    width: 640
    height: 480
    title: qsTr("Stack")

    header: ToolBar {
        contentHeight: toolButton.implicitHeight

        ToolButton {
            id: toolButton
            text: stackView.depth > 1 ? "\u25C0" : "\u2630"
            font.pixelSize: Qt.application.font.pixelSize * 1.6
            onClicked: {
                if (stackView.depth > 1) {
                    stackView.pop()
                } else {
                    drawer.open()
                }
            }
        }

        Label {
            text: stackView.currentItem.title
            anchors.centerIn: parent
        }
    }

    Drawer {
        id: drawer
        width: window.width * 0.66
        height: window.height

        Column {
            anchors.fill: parent

            ItemDelegate {
                text: qsTr("Page 1")
                width: parent.width
                onClicked: {
                    stackView.push("Page1Form.qml")
                    drawer.close()
                }
            }
            ItemDelegate {
                text: qsTr("Page 2")
                width: parent.width
                onClicked: {
                    stackView.push("Page2Form.qml")
                    drawer.close()
                }
            }
        }
    }

    StackView {
        id: stackView
        initialItem: "HomeForm.qml"
        anchors.fill: parent
    }
}
  1. Use the Loader here you will dynamically load files during execution, the disadvantage of this method is that if you switch often, it will be time consuming.

Example:

import QtQuick 2.0

Item {
    width: 200; height: 200

    Loader { id: pageLoader }

    MouseArea {
        anchors.fill: parent
        onClicked: pageLoader.source = "Page1.qml"
    }
}
  1. You can create a class in C++ that will be given to an already initialized QML object to an empty qml form. thus, mono place individual components into libraries and use them as plugins (use qqmlcomponent).

Upvotes: 1

Related Questions