0

我正在尝试创建一个 TabBar 具有已连接布局的子项的预览图像。但是,在添加多个选项卡后(确切数量取决于选项卡中元素的数量)QML 会引发错误,并且 PreviewTabBar 会丢失其所有内容子项。

以下是一个最小的工作示例:

我的 main.qml:

import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    StackLayout {
        id: swipeView
        anchors.fill: parent
        currentIndex: tabBar.currentIndex
    }

    Timer {
        interval: 50; running: true; repeat: true
        onTriggered: addTab()
    }

    function addTab() {
        console.log("add Tab")
        var component = Qt.createComponent("qrc:/TabContent.qml")
        if(component.status !== Component.Ready)
            console.log("component not ready")
        var item = component.createObject(swipeView)
        tabBar.addTab(item)
        tabBar.currentIndex = tabBar.contentChildren.length - 1
        console.log("current index " + tabBar.currentIndex)
    }


    header: PreviewTabBar {
        id: tabBar
        currentIndex: swipeView.currentIndex
    }
}

PreviewTabBar.qml 包含内容的预览:

import QtQuick 2.8
import QtQuick.Controls 2.1

TabBar {
    signal closeCurrentTab

    clip: true
    background: Rectangle {
        color: "white"
    }

    function addTab(imageSource) {
        var component = Qt.createComponent("PreviewTabButton.qml")
        if(component.status !== Component.Ready)
            console.log("component not ready")
        else {
            var item = component.createObject()
            item.setSource(imageSource)
            addItem(item)
        }
    }

    function closeTab() {
        console.log("closeTab")
        closeCurrentTab()
    }
}

最后但并非最不重要的是 PreviewButton.qml 使用 ShaderEffectSource 来呈现预览:

import QtQuick 2.8
import QtQuick.Controls 2.1

TabButton {
    height: 80
    width: 140

    function setSource(source) {
        preview.sourceItem = source
    }

    contentItem: ShaderEffectSource {
        id: preview
    }
}

这个例子在我的机器上得到了大约 80 个标签,之后 PreviewTabBar 失去了它所有的孩子(不是 StackLayout)。然而,在具有更复杂选项卡内容的现实示例中,我最多只能获得大约 8 个选项卡。我可能做错了什么?

这是应用程序输出的相关部分:

qml: current index 99
qml: add Tab
file:///usr/lib/qt/qml/QtQuick/Controls.2/TabButton.qml:65: TypeError:     Cannot read property of null
qml: current index 100
qml: add Tab
qml: current index 1

我尝试在回调中完成动态组件创建,如下所述:

http://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html#creating-a-component-dynamically

然而,这并没有带来任何改善。

这是示例项目的链接:

https://www.file-upload.net/download-12341284/tabtestshader.zip.html

4

1 回答 1

1

最可能的原因是第 17 行PreviewTabBar.qml

var item = component.createObject()

由于您在 -function 中没有设置父createObject()级,GarbageCollector 往往会疯狂运行,并删除您的对象,即使它仍然被引用。
虽然没有以这种方式记录,但您应该始终传递一个父对象,以确保它在 GC 中幸存下来。

更稳定的方法是从模型生成,并在-functionsTabs中添加相应的模型条目。addTab

顺便说一句:每次调用一个addTab-functions 时都会创建一个新组件。你为什么不声明一次

 Component {
     id: myComp1
     ...
 }

并从中创建对象?

于 2017-02-27T17:54:30.427 回答