如何在 QML 中动态创建 Popup

Posted

技术标签:

【中文标题】如何在 QML 中动态创建 Popup【英文标题】:How dynamically creates Popup in QML 【发布时间】:2017-03-27 04:58:43 【问题描述】:

当我尝试使用 Qt.createQmlObject(...)Qt.createComponent(...) 动态创建 Popup 时,出现异常:

QML 弹出窗口:找不到任何可在其中打开弹出窗口的窗口。

这是我的代码:

var popup1 = Qt.createQmlObject('import QtQuick 2.8; import QtQuick.Controls 2.1; Popup  id: popup; x: 100; y: 100; width: 200; height: 300; modal: true; focus: true; closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent; visible: false ',
                                window,
                                "DynamicPopup");
popup1.open()

var popupComponent = Qt.createComponent("qrc:/TestPopup.qml")
var popup2 = popupComponent.createObject(window);
popup2.open()

TestPopup.qml:

import QtQuick.Window 2.2
import QtQuick.Controls 2.1

Popup 
    x: 100
    y: 100
    width: 200
    height: 300
    modal: true
    focus: true
    closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
    visible: false

【问题讨论】:

【参考方案1】:

Popup 没有继承QQuickItem,默认情况下它是QML Window 的父级,如果您使用QQuickWidget,则不会实例化。因此传递parent 应该如下完成:

var popupComponent = Qt.createComponent("qrc:/TestPopup.qml")
var popup2 = popupComponent.createObject(window, "parent" : window);
popup2.open()

【讨论】:

@A.J,在你的例子中window 是什么?尝试将Popup绑定到QQuickItem 好吧,我的窗口是一个ApplicationWindow。非常感谢。【参考方案2】:

父元素必须是继承自QQuickItem的元素

例子:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.1

Window 
    id: win
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Row
        Button
            id: item1
            text: "btn1"
            onClicked: 
                var popup1 = Qt.createQmlObject('import QtQuick 2.8; import QtQuick.Controls 2.1; Popup  id: popup; x: 100; y: 100; width: 200; height: 300; modal: true; focus: true; closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent; visible: false ',
                                                item1,
                                                "DynamicPopup");
                popup1.open()

            
        

        Button
            id: item2
            text: "btn2"
            onClicked: 
                var popupComponent = Qt.createComponent("qrc:/TestPopup.qml")
                var popup2 = popupComponent.createObject(item2);
                popup2.open()
            

        

    

方法一:

方法二:

【讨论】:

【参考方案3】:

Popup 需要以 Item 为父对象,window 不是一个。 你应该改用window.contentItem

【讨论】:

【参考方案4】:

使用 Loader 动态加载弹出窗口的好方法:

Loader 
    id: popupLoader

    active: false
    source: "qrc:/TestPopup.qml"
    onLoaded: item.open()


function openMyPopup() 
    if( popupLoader.active )
        popupLoader.item.open()
    else
        popupLoader.active = true

【讨论】:

以上是关于如何在 QML 中动态创建 Popup的主要内容,如果未能解决你的问题,请参考以下文章

如何为 QML 创建一个动态的全局主题?

如何在 QML 中创建动态委托?

如何将动态创建的 qmlcomponent 对象绑定到另一个动态创建的 qmlcomponent 对象的属性?

在 QML 中获取对动态创建的 ChartView 的引用

QML 创建 TreeView 动态模型的正确方法是啥?

使用 Python 从 QML 中动态创建的列表中访问数据