Game menu



  • Hi all,

    right now I am in process of making a game and currently I am designing my game menu classes.

    I would like to have the menu, like standard flash games have, e.g. when I click on a button in the
    menu widget a new widget replaces it in the same window with another set of buttons representing a submenu, ...

    To do this I was thinking of using QStackedWidget, but I was not able to figure out an elegant way
    to do the back button.

    I came up with something like:
    @static_cast<CMainWindow *>(parent())->setCurrentIndex(0);@
    where this is implemented in a widget added to CMainWindow widget, which is derived from QStackedWidget.
    However this seems to me a kind of hackish.

    Also I came across the QWizard widget, which has a similar behaviour to what I want,
    but I deem that dialog widget is not the right choice for game menu.

    So my question is what do you think would be a good approach to design a menu like ?
    I even tried to go through qt demos and google, but none of them had an example on this kind of thing.

    Thanks in advance for any good advice or links to examples



  • So i will reply to myself:

    After taking inspiration from "this":http://stackoverflow.com/questions/9651976/transitioning-between-menu-screens-with-qstatemachine SO post and "this":http://pastebin.com/YhbHHJNe code snippet linked in the last comment of the accepted answer, I came up with following solution:

    @class CMenuScreenWidget : public QStackedWidget
    {
    Q_OBJECT

    public:
    explicit CMenuScreenWidget(QWidget *parent = 0)
    : QStackedWidget(parent)
    { }

    protected:
    /**
    * This method will set up a mapping between signals and widgets.
    * This means that when a signal of a sender is triggered,
    * the menuscreen will be switched to make the widget a currently
    * displayed widget.
    *
    * @param sender connect to signals from this object
    * @param signal connect to this particular signal
    * @param widget make this widget current upon triggering a signal
    */
    void setMapping(QObject *sender, const char *signal, QWidget *widget);

    private slots:
    void switchWidget(void);

    private:
    QHash<QObject *, QWidget *> m_mapping; /// to keep mapping between signal senders and widgets
    };@

    @/**
    */
    void CMenuScreenWidget::setMapping(QObject *sender, const char *signal, QWidget *widget)
    {
    addWidget(widget);
    connect(sender, signal, SLOT(switchWidget()));
    m_mapping[sender] = widget;
    return;
    }

    /**
    */
    void CMenuScreenWidget::switchWidget(void)
    {
    setCurrentWidget(m_mapping[sender()]);
    return;
    }
    @

    And usage could be for example like this:

    @class CMainMenuWidget;
    class CSinglePlayerMenuWidget;

    /**
    */
    class CMainWindow : public CMenuScreenWidget
    {
    Q_OBJECT

    public:
    explicit CMainWindow(QWidget *parent = 0);

    private:
    CMainMenuWidget *m_main_menu;
    CSinglePlayerMenuWidget *m_single_player;
    };
    @

    @CMainWindow::CMainWindow(QWidget parent)
    : CMenuScreenWidget(parent),
    m_main_menu(0),
    m_single_player(0)
    {
    /
    create widgets */
    m_main_menu = new CMainMenuWidget;
    m_single_player = new CSinglePlayerMenuWidget;

    /* set signals */
    connect(m_main_menu, SIGNAL(exitTriggered()), SLOT(close()));

    /* set up menu mappings and connections between menu screens */
    setMapping(m_main_menu, SIGNAL(singlePlayerTriggered()), m_single_player);
    setMapping(m_single_player, SIGNAL(backTriggered()), m_main_menu);

    /* set current widget */
    setCurrentWidget(m_main_menu);
    }@

    While not the most efficient, I hope this solution is flexible enough for changes in UI,
    which I think is quite an important quality of UI-s in general.


Log in to reply
 

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