ListView in subwindow triggers immediate close, or

2019-03-03 02:13发布

问题:

I have rather strange scenario whereby if I launch a subwindow that contains a ListView with a moderately complex delegate and enough items to comfortably exceed the visible area, the entire subwindow will immediately close on launch.

Reducing the complexity of the delegate will allow the window to open, but then rapidly scrolling the ListView will forcibly close it.

This SSCCE triggers the effect on my laptop, but on a more powerful machine it may only do it whilst scrolling (or perhaps the delegate may need to be more complex):

import QtQuick 2.3
import QtQuick.Window 2.0

Window {
    width: 300
    height: 200

    Component.onCompleted: {
        win.createObject( null );
    }

    Component {
        id: win

        Window {
            width: 600
            height: 400

            visible: true

            ListView {
                id: view
                anchors.fill: parent

                model: 100

                boundsBehavior: Flickable.StopAtBounds
                clip: true

                delegate: Rectangle {
                    width: view.width
                    height: 24

                    property int debugLevel: index % 3
                    property int timestamp: index * 1000
                    property int message: index

                    color: "darkgray"

                    Row {
                        anchors.fill: parent

                        Repeater {
                            id: delegateRepeater

                            property list< QtObject > roleModel: [
                                QtObject {
                                    property string label: timestamp
                                    property int itemWidth: 100
                                },
                                QtObject {
                                    property string label: debugLevel
                                    property int itemWidth: 100
                                },
                                QtObject {
                                    property string label: message
                                    property int itemWidth: view.width - 100 - 100
                                }
                            ]

                            model: roleModel

                            Item {
                                width: itemWidth
                                anchors {
                                    top: parent.top
                                    bottom: parent.bottom
                                }

                                Text {
                                    anchors {
                                        fill: parent
                                        leftMargin: 4
                                    }

                                    verticalAlignment: Text.AlignVCenter

                                    text: label
                                    elide: Text.ElideRight
                                }

                                Rectangle {
                                    anchors {
                                        top: parent.top
                                        bottom: parent.bottom
                                        right: parent.right
                                    }

                                    width: 1

                                    visible: index != ( delegateRepeater.count - 1 )
                                    color: "white";
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

There doesn't seem to be any particular part of the code that is causing the problem, removing any of the objects in the delegate reduces the probability of the subwindow closing.

I've added the debugging tag because my main problem is that this effect produces no debug output. If I add a breakpoint into the subwindow's destruction handler (Component.onDestruction) then there is a single stack entry pointing at the model: roleModel statement - but removing the entire Repeater and replacing with a copy-and-pasted equivalent yields the same results minus the stack entry.

So I would be grateful is anyone knows of a way of getting more information from this pure QML example.

回答1:

As noted by @BaCaRoZzo the changing of behaviour by modifying the delegate code seems to be an unrelated side-issue.

The real cause is because it turns out you cannot create new root contexts (i.e. top-level windows) from QML. This was hinted at being resolved when Qt Quick Components were released, but the blog post boasting of Window doesn't explicitly state this. Creating a new Window and passing null for the parent technically works but the result seems to be very unstable.

Thankfully in my circumstance I'm creating a QML/C++ application so I've solved the issue by creating new root contexts from Q_INVOKABLE methods on the C++ side. But if you're developing a pure QML application, it seems that you are out of luck.