Search code examples
qtpopupqml

How to set objectName for PopupItem from QML?


QML Popup and derived controls are creating a PopupItem object which is a visual representation of it, but Popup itself is parented to the contentData of the application window. objectName specified for Popup is not applied to PopupItem. For example, the following application:

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Popup Test")

    Button {
        text: "Open"
        onClicked: dummyPopup.open()
    }

    Popup {
        id: dummyPopup
        objectName: "dummyPopup"
        x: 100
        y: 100
        width: 200
        height: 300
        modal: true
        focus: true
    }
}

creates PopupItem with empty objectName Empty objectName

Is there a way to set objectName for PopupItem from QML?


Solution

  • Set the objectName of its contentItem upon completion:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Controls 2.12
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: qsTr("Popup Test")
    
        Button {
            text: "Open"
            onClicked: dummyPopup.open()
        }
    
        Popup {
            id: dummyPopup
            objectName: "dummyPopup"
            x: 100
            y: 100
            width: 200
            height: 300
            modal: true
            focus: true
    
            Component.onCompleted: {
                contentItem.objectName = "foo"
                print(contentItem)
            }
        }
    }
    

    By the way, if this is for auto tests, I have a hack in C++ that avoids the need to give an objectName to the contentItem:

    QObject *TestHelper::findPopupFromTypeName(const QString &typeName) const
    {
        QObject *popup = nullptr;
        foreach (QQuickItem *child, overlay->childItems()) {
            if (QString::fromLatin1(child->metaObject()->className()) == "QQuickPopupItem") {
                if (QString::fromLatin1(child->parent()->metaObject()->className()).contains(typeName)) {
                    popup = child->parent();
                    break;
                }
            }
        }
        return popup;
    }
    

    You can then use that function like this in your test:

    const QObject *newProjectPopup = findPopupFromTypeName("NewProjectPopup");
    QVERIFY(newProjectPopup);
    QTRY_VERIFY(newProjectPopup->property("opened").toBool());