Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Dynamic menu in Qt



  • Hello,

    I'm French so sorry if my english is not perfect :)

    I'm pretty knew on Qt and I'm stuck with something that I think is supposed to be simple but maybe it is impossible in Qt.
    I'm recreating the fight system of Pokemon games and after doing it on console, I'm trying to adapt it on Qt to have a graphical interface.

    For now, I have my main window with a QGridLayout "hud" that contain a QGridLayout on the top right of the screen with the opponent's pokemon infos, another QGridLayout on the bottom left of the screen with the player's pokemon infos and a QVBoxLayout "menu" on the bottom right of the screen with 4 QPushButtons :

    • Attack
    • Team
    • Bag
    • Run

    What I want to do know is when we click on the "Attack" button, the menu change and now show the pokemon's capacity's names on the 4 QPushButtons instead of the 4 1st menu buttons.

    Thanks for your help and time :)
    Tequi.


  • Lifetime Qt Champion

    @Tequiloutre You can either reuse the existing buttons (change their text, and store the current state in a variable, so you know what to do if a button is pressed). Or you design distinct widgets for both states. You can use https://doc.qt.io/qt-5/qstackedwidget.html to easily switch between both states.



  • Hello @jsulm

    Thanks for your reply.

    I've tried QStackedWidget that seems right for this case, but it doesn't work, I've certainly done something wrong :/

    I created two QPushButton for the two possibilities :

    QPushButton *m_button_attack = new QPushButton("Attaquer");
    QPushButton *m_button_capacity_1 = new QPushButton("Capacité 1");
    

    Then I created the QStackedWidget with those QPushButton :

    QStackedWidget *m_button_1 = new QStackedWidget;
    m_button_1->addWidget(m_button_attack);
    m_button_1->addWidget(m_button_capacity_1);
    

    And I connected this QStackedWidget to change index on click (maybe I've made a mistake here ?)

    QObject::connect(m_button_attack, SIGNAL(clicked()), m_button_1, SLOT(setCurrentIndex(1)));
    

    And this QStackedWidget is inside some layouts to be showned in the right place.
    The problem is that the QStackedWidget shows but do nothing on click and I have this error :

    QObject::connect: No such slot QStackedWidget::setCurrentIndex(1) in ../Pokemon/Window.cpp:111
    

  • Lifetime Qt Champion

    @Tequiloutre said in Dynamic menu in Qt:

    QObject::connect(m_button_attack, SIGNAL(clicked()), m_button_1, SLOT(setCurrentIndex(1)));

    This is not how signals/slots work - you can't pass parameters like this while connecting signals with slots.
    Use new connect syntax and lambdas:

    connect(m_button_attack, &QPushButton::clicked, [this](){ m_button_1->setCurrentIndex(1); });
    


  • @jsulm

    I tried your solution but I have an error about the connect syntax you gave me :

    erreur : variable 'm_button_1' cannot be implicitly captured in a lambda with no capture-default specified
    

  • Lifetime Qt Champion

    Then also capture m_button_1 ... https://en.cppreference.com/w/cpp/language/lambda



  • I don't completely understand but I've made some research and the connect seems to work when declared like this :

    QObject::connect(m_button_attack, &QPushButton::clicked, m_button_1, [=]() { m_button_1->setCurrentIndex(1); });
    

    Thanks you all for your help :)
    Have a good and safe day :D


  • Moderators

    @Tequiloutre said in Dynamic menu in Qt:

    I don't completely understand but I've made some research and the connect seems to work when declared like this :

    When you write [=] in your lambda, it means "capture all variables by-value". So, you can use all variables inside your lambda.

    When you write [this] in your lambda, it means "capture this by-value". So, you can use this inside your lambda, but you cannot use other external variables.



  • This post is deleted!

Log in to reply