[Solved]Basic Question: How to get access to dynamically created buttons?



  • Hi,

    I am writing on my first application and I am completely new to Qt. I did a lot of reading recently and got confused somehow.

    I have looked at many example projects and forum topics but couldn't apply the hints and solutions on my application.
    So, this is my problem:

    I dynamically created some custom navigation buttons with QML. That means that I have my QML-file MainMenuButton.qml and used a JavaScript Function to create them. So good so far. Now I want to show a different content each time I click on the specific button and adjust the visibility of images inside the other menu button.

    As far as I know I should use signals and slots to resolve this problem and somehow use findChildren to find the other buttons to change their properties or am I thinking too complicated? Is there an easier way to get access to other QML elements from the clicked button?

    So here is my code:
    MainMenuButton.qml

    @
    Item {
    ...
    Text {
    id: mainMenuButtonLabel
    anchors.centerIn: parent
    text: labelText
    color: "#444"
    font.bold: true
    font.pointSize: 16
    }
    MouseArea {
    id: buttonMouseArea

            // Anchor all sides of the mouse area to the rectangle's anchors
            anchors.fill: parent
            hoverEnabled: true
            onEntered: {
                mainMenuButtonOverlay.color = "#c8c8c8"
                mainMenuButtonLabel.color = "lightgrey"
                mainMenuDropDown.open()
            }
            onExited: {
                mainMenuButtonOverlay.color = "#444"
                mainMenuButtonLabel.color = "#444"
                mainMenuDropDown.close()
            }
            onClicked: {
                mainMenuDropDown.close()
                mainMenuArrow.visible = true;
                mainMenuButton.invisible(mainMenuButton.index);
                mainMenuArrow.clearArrows();
            }
        }
    
        Component.onCompleted: {
            if(index == 6) {
                mainMenuButtonIcon.anchors.rightMargin = -5;
            }
        }
    
        Image {
            id: mainMenuArrow
            source: "Rsc/Icons/mainMenuArrow.png"
            anchors.horizontalCenter: parent.horizontalCenter
            visible: false
            sourceSize.height: 9
            y: parent.height - 7
        }
    }
    

    @

    main.cpp
    @
    #include "main.h"

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    
    return app.exec();
    

    }
    @

    I created a class to keep the navigation logic inside.
    mainMenuNavigation.h
    @
    #ifndef MAINMENUNAVIGATION_H
    #define MAINMENUNAVIGATION_H

    #include <QObject>

    class MainMenuNavigation : public QObject
    {
    Q_OBJECT

    public:
    MainMenuNavigation(&#41;;
    Q_INVOKABLE void clearArrows();
    
    signals:
    void arrowCleared();
    
    private:
    

    };

    #endif // MAINMENUNAVIGATION_H
    @

    mainMenuNavigation.cpp
    @
    #include "mainmenunavigation.h"

    MainMenuNavigation::MainMenuNavigation(){

    }

    void MainMenuNavigation::clearArrows()
    {
    emit arrowCleared();
    }
    @

    As you see I didn't apply any logic yet, because I received the error:
    qrc:///MainMenuButton.qml:93: TypeError: Property 'clearArrows' of object QQuickImage(0x101c9bff0) is not a function

    I would be so happy if you could help me with that problem.
    And what I basically want to achieve is to make the mainMenuArrow visible for the current clicked button and make all arrows of other buttons invisible.
    Thanks!


  • Moderators

    Hi,

    bq. qrc:///MainMenuButton.qml:93: TypeError: Property ‘clearArrows’ of object QQuickImage(0×101c9bff0) is not a function

    This is because mainMenuArrow clearly doesnot have that function.
    In other words you cant call clearArrows() of MainMenuNavigation class using the Image element's id.

    One simple solution would be to create a property variable for each MainMenuButton's instance, this will hold a unique value (for eg. a number). Then keep a global property which will hold the currently clicked MainMenuButton's unique value. Then bind equivalent expression check to the visible property of Image, thus when you click, the global property will change and this expression will execute and corresponding value for visible will be set.
    Is this what you are looking for ?



  • My inputs...You have written QML and C++. You are trying to use clearArrows(....) function from QML. However this functions in C++ object. I did not see any registration of C++ Item with QML. I suggest you to look at the QML and C++ integration completely. Based on this you can make your logic work.



  • Thank you for answering! You are right. MainMenuArrow cannot call this function. But even if I write
    @
    mainMenuNavigation.clearArrows();
    @

    doesn't work. There musst be something missing. I guess that I have to make an instance of MainMenuNavigation. But what do I have to do with it?

    Making a global property variable might solve the problem for now. But I would appreciate it if someone could tell me how to use signals and slots correctly. :)



  • Hi Dheerendra, I tried the documentation already. And I have read it many times. I am just afraid my C++ is a little rusty. So I have problems to understand the example code.


  • Moderators

    bq. There musst be something missing. I guess that I have to make an instance of MainMenuNavigation. But what do I have to do with it?

    Have a look at "this":http://qt-project.org/doc/qt-5/qtqml-cppintegration-contextproperties.html#setting-an-object-as-a-context-property

    Edit: IMO, accessing the properties of QML through this class would be more tedious.



  • Thanks! That was exactly what I was looking for!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.