Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QML Registered classes loses visibility upon reloading qml

QML Registered classes loses visibility upon reloading qml

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
1 Posts 1 Posters 471 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • TrinadhT Offline
    TrinadhT Offline
    Trinadh
    wrote on last edited by
    #1

    I have a simple app.
    In homepage, i have a list of menu-items.
    When user clicks on menu-item, menu-item opens.
    User can change the options of the selected menu-item.
    Before applying the changes to the selected-menu-item-options, user needs to confirm.

    Issue :
    I have exposed some enums in my business logic.
    The enums were coming correctly for the first time when app is loaded.
    But when qml (corresponding to any menu-item) is reloaded, i am getting an undefined reference error.

    Typically i am doing the following actions in my app.

    I have registered a class(for exposing enums to QML) in main.cpp.

    Registered class MyEnums

    class MyEnums : public QObject
    {
        Q_OBJECT
        Q_ENUMS(FILE_TYPE)
    
        public:
        enum FILE_TYPE {
           QT_FILE_TYPE_REGULAR = 1,
           QT_FILE_TYPE_SOFTLINK
        };
    };
    

    main.cpp

    int main(int argc, char* argv[]) 
    {
        QApplication qapp(argc, argv);
        QDeclarativeView* view = new QDeclarativeView();
        ...
        qmlRegisterUncreatableType<MyEnums>("MyEnums", 1, 0, "MyEnums", "");
        ...
        view->setSource(QUrl::fromLocalFile("File:///Main.qml"));
        ...
        return qapp.exec();
    }
    

    Main.qml manages all the qml's.
    It has couple of functions.

    gotoHome() : to load home screen

    showPopup() : to load confirmation screen

    dismissPopup() : to dismiss confirmation screen

    When confirmation is dismissed a signal will be emitted, app can connect to this signal to perform any business logic.

    Main.qml

    import QtQuick 1.1
    Rectangle {
        id: main
        ...
        Loader {
            id: appLoader  // shows menu-items
            source: ""
            visible: true
        }
        Loader {
            id: popupLoader // to show confirmation for all apps-options
            source: ""
            visible: false
        }
        ...
        signal loadQml(string file)
        onLoadQml : {
            appLoader.source = file
            appLoader.visible = true
            popupLoader.visible = false
            appLoader.forceActiveFocus()
        }
        ...
        function gotoHome() {
             loadQml("Home.qml")
        }
        ...
        property variant activeQmlRef
        signal leftButtonClicked(variant qmlId)
        signal rightButtonClicked(variant qmlId)
    
        function showPopup(id, text) {
            activeQmlRef = id
            popupLoader.source = "Popup.qml"
            popupLoader.visible = true
            appLoader.visible = false
            popupLoader.forceActiveFocus()
        }
    
        function dismissPopup(isLeftButtonClicked) {
            popupLoader.visible = false
            appLoader.visible = true
            appLoader.forceActiveFocus()
            if (isLeftButtonClicked) {
                leftButtonClicked(activeQmlRef)
            } else {
                rightButtonClicked(activeQmlRef)
            }
        }
        ...
        Component.onCompleted: {
            ...
            gotoHome()
        }
    }
    

    Home.qml contains the menu items list

    import QtQuick 1.1
    Rectangle {
        ...
        ListModel {
            id: menuListModel
        }
        ListView {
            id: menuListView
            model: menuListModel
            ...
            delegate: MyDelegate { title: name, url: qmlSrc }
        }
        ...
        Component.onCompleted: {
            menuListModel.append({ "name" : "APP1", "qmlSrc" : "app1.qml" });
            menuListModel.append({ "name" : "APP2", "qmlSrc" : "app2.qml" });
            ...
        }
    }
    

    MyDelegate.qml

    import QtQuick 1.1
    Rectangle {
        property string name
        property string qmlSrc
        ...
        Text {
            ...
            text: name
        }
    
        MouseArea {
            anchors.fill: parent
            onClicked: {
                main.loadQml(qmlSrc)
            }
        }
    }
    

    Popup.qml

    import QtQuick 1.1
    Item {
        id: popup
        ...
        Text {
            id: title
            ...
        }
        Text {
            id: msg
            ...
        }
        Rectangle {
            id: leftButton
            ...
            MouseArea {
                ...
                onClicked : {
                    main.dismissPopup(true)
                }
            }
        }
        Rectangle {
            id: rightButton
            ...
            MouseArea {
                ...
                onClicked : {
                    main.dismissPopup(false)
                }
            }
        }
    }
    

    app1.qml Qml for menu-item1.

    Lets say this item has two options. (app1Option1 & app1Option2)

    When user clicks on any option, a confirmation-prompt appears and the changes (business-logic + ui-changes) will happen only when user clicks on confirm-button on the confirmation-prompt.

    function onConfirm() is connected to main.leftButtonClicked() signal and the changes(business-logic + ui-changes) are performed in this function.

    I am using "MyEnums" class in this function.

    For the first-time when the app is loaded, i am getting enum values correctly.

    But when the same qml is reloaded again, i am getting "undefined reference error for <b>MyEnums</b>".

    import QtQuick 1.1
    import MyEnums 1.0
    
    Rectangle {
        id: app1Options
    
        Rectangle {
            id: header
            ...
            MouseArea {
                onClicked : {
                    main.gotoHome()
                }
            }
        }
        ....
        Rectangle {
            id: app1Option1
            ...
            MouseArea {
                onClicked : {
                    main.showPopup(app1Options, "app1Option1Text");
                }
            }
        }
        Rectangle {
            id: app1Option2
            ...
        }
        ...
        // Following function is triggered: 
        // - when user clicks on "app1Option1" (popup appears)
        // - When user again clicks on "Confirm" (id:leftButton in Popup.qml)
        function onConfirm {
             ...
            /*
             * When app is loaded initially (for the first time), output : MyEnums.QT_FILE_TYPE_REGULAR [1]
             * When the screen is loaded again
             * - goback to home by clicking on header-area
             * - click APP1 on home
             * - click on "app1Option1"
             * - click on "Confirm" in popup
             * Output : undefined reference to "MyEnums"
             */
            console.log("MyEnums.QT_FILE_TYPE_REGULAR [" + MyEnums.QT_FILE_TYPE_REGULAR + "]")
            ...
        }
    
        function onCancel {
            ...
        }
    
        Component.onCompleted: {
            main.leftButtonClicked.connect(onConfirm)
            main.rightButtonClicked.connect(onCancel)
        }
    }
    

    I do not see any warnings/errors during build-time or run-time. (except for the above one)

    Could anyone suggest me what am i doing wrong here.

    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved