How can I create a new window from within QML?

26,663

Solution 1

There is no way to create top-level windows using only built-in QML functionality.

However there's a project on Qt Labs called Desktop Components, which among other things contains a Window component, which allows you to create new top-level windows.

Solution 2

You can do it by using Qt.createComponent. Example (using Qt 5.3):

main.qml

import QtQuick 2.3
import QtQuick.Controls 1.2

ApplicationWindow {
    id: root
    width: 200; height: 200
    visible: true

    Button {
        anchors.centerIn: parent
        text: qsTr("Click me")

        onClicked: {
            var component = Qt.createComponent("Child.qml")
            var window    = component.createObject(root)
            window.show()
        }
    }
}

Child.qml

import QtQuick 2.3
import QtQuick.Controls 1.2

ApplicationWindow {
    id: root
    width: 100; height: 100

    Text {
        anchors.centerIn: parent
        text: qsTr("Hello World.")
    }
}
Share:
26,663
opatut
Author by

opatut

We need to go beyond the condemnation of spaghetti code to the active encouragement of ravioli code. [found here]

Updated on October 14, 2020

Comments

  • opatut
    opatut over 3 years

    Is there a way to create a completely new window instance, as a child window of the main QML window in a QmlApplication?

    // ChildWindow.qml
    Rectangle {
        id: childWindow
        width: 100
        height: 100
        // stuff
    }
    
    // main.qml
    Rectangle {
        id: window
        width: 1000
        height: 600
    
        MouseArea {
            anchors.fill: parent
            onClicked: createAWindow(childWindow);
        }
    }
    

    I am trying to avoid writing a Q_OBJECT class just for instanciating the new window within a new QmlApplicationViewer.

  • opatut
    opatut over 12 years
    That looks awesome, thank you. My next step would have been to search for these Desktop Components, since I need them anyways. Didn't think they would do new windows, too ;)
  • User
    User almost 10 years
    Inside main i am getting this error "qrc:///main.qml:59: ReferenceError: root is not defined", when i press click me button ?
  • Kknd
    Kknd almost 10 years
    It runs as expected here when I try it with qmlscene main.qml.
  • User
    User almost 10 years
    I am using QT 5.3.1 and i have QtQuick 2.2, QtQuick.Controls 1.1 instaed urs 2.3 and 1.2. Is this an issue ?
  • mozzbozz
    mozzbozz over 9 years
    @User: "root is not defined" sounds like you forgot to ad the id: root to the ApplicationWindow in the main.qml-file... Also why not try importing the newer QtQuick.Controls? Most likely this will not break anything but improve small things...
  • Mohammad Kanan
    Mohammad Kanan about 5 years
    The Error "root not defined" is because its unquoted. this way should work: var window = component.createObject("root")
  • Stefan Fabian
    Stefan Fabian almost 4 years
    @MohammadKanan that is absolutely wrong. Please read the documentation on frameworks you use rather than guessing what might be required. The parameter passed to createObject is the parent of the created component. You can omit that but then you have to keep a reference to the object or it will be destroyed. Passing a string there doesn't make any sense.
  • Mohammad Kanan
    Mohammad Kanan almost 4 years
    @StefanFabian, I didnt state anything opposing the parent relationship .. , honestly I totally forgot the details that made me put this commit. That said, quoting still works with or without the id = root on top parent ... it might NOT however be correct as to set that specific 'root' parent to the created object .. I would agree to that ..
  • Stefan Fabian
    Stefan Fabian almost 4 years
    No, you stated that the ID should be quoted and that is incorrect. The method expects a QtObject as parameter and AFAIK a string is not a QtObject. Hence, this is undefined behavior. I assume it works because it ignores your invalid parameter and just assumes no parent but I haven't looked at the relevant code so that's just a guess.