22

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
  • 6,708
  • 5
  • 32
  • 37

2 Answers2

48

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.")
    }
}
Joe
  • 811
  • 1
  • 8
  • 14
Kknd
  • 3,033
  • 26
  • 29
  • 1
    Inside main i am getting this error "qrc:///main.qml:59: ReferenceError: root is not defined", when i press click me button ? – User Aug 07 '14 at 02:27
  • It runs as expected here when I try it with qmlscene main.qml. – Kknd Aug 07 '14 at 12:23
  • 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 ? – User Aug 07 '14 at 13:55
  • 2
    @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... – mozzbozz Feb 04 '15 at 13:29
  • 3
    The Error "root not defined" is because its unquoted. this way should work: `var window = component.createObject("root")` – Mohammad Kanan Jun 19 '19 at 23:41
  • 2
    @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](https://doc.qt.io/qt-5/qml-qtqml-component.html#createObject-method). 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. – Stefan Fabian Sep 13 '20 at 17:07
  • @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 .. – Mohammad Kanan Sep 14 '20 at 00:48
  • 2
    No, you stated that the ID should be quoted and that is [incorrect](https://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html#creating-a-component-dynamically). 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. – Stefan Fabian Sep 15 '20 at 06:35
2

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.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • 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 ;) – opatut Nov 30 '11 at 16:20