Переход между экранами меню с помощью QStateMachine - PullRequest
0 голосов
/ 11 марта 2012

Я рассматриваю возможность перехода между экранами меню в игре, используя QStateMachine. Однако я не уверен, как запустить какой-то код (например, show() a QWidget) при переходе между состояниями. Я могу сделать это довольно легко с простыми старыми сигналами (см. Закомментированный код), но я полагаю, что я мог бы сделать некоторую причудливую анимацию после переключения экранов с помощью переходов.

Вот мой код:

Редактировать: обновлено в соответствии с предложением Койинга.

ApplicationWindow.h :

#include <QtGui>
#include <QStateMachine>

#include "MainMenu.h"
#include "LoadGameMenu.h"

class ApplicationWindow : public QMainWindow
{
    Q_OBJECT
public:
    ApplicationWindow();
private slots:
    void mainMenuButtonClicked();
    void loadGameMenuButtonClicked();
private:
    MainMenu* mainMenu;
    LoadGameMenu* loadGameMenu;

    QStateMachine stateMachine;

    QStackedWidget* stack;
};

ApplicationWindow.cpp

ApplicationWindow::ApplicationWindow()
{
    resize(800, 600);

    stack = new QStackedWidget(this);

    mainMenu = new MainMenu();
    setCentralWidget(mainMenu);
    loadGameMenu = new LoadGameMenu();

    QState* mainMenuState = new QState();
    QState* loadGameMenuState = new QState();

    QAbstractTransition* loadTransition = mainMenuState->addTransition(
        mainMenu, SIGNAL(loadGameClicked()), loadGameMenuState);
    connect(loadTransition, SIGNAL(triggered()), this, SLOT(loadGameMenuButtonClicked()));

    QAbstractTransition* mainMenuTransition = loadGameMenuState->addTransition(
        loadGameMenu, SIGNAL(backToMainMenuClicked()), mainMenuState);
    connect(mainMenuTransition, SIGNAL(triggered()), this, SLOT(mainMenuButtonClicked()));

    stateMachine.addState(mainMenuState);
    stateMachine.addState(loadGameMenuState);

    stateMachine.setInitialState(mainMenuState);
    stateMachine.start();
}

void ApplicationWindow::mainMenuButtonClicked()
{
    setCentralWidget(mainMenu);
}

void ApplicationWindow::loadGameMenuButtonClicked()
{
    setCentralWidget(loadGameMenu);
}

LoadGameMenu.h:

#include <QtGui>

class LoadGameMenu : public QWidget
{
    Q_OBJECT
public:
    LoadGameMenu();
signals:
    void backToMainMenuClicked();
private:
    QPushButton* loadGameButton;
    QPushButton* backToMainMenuButton;
};

LoadGameMenu.cpp:

#include "LoadGameMenu.h"

LoadGameMenu::LoadGameMenu()
{
    loadGameButton = new QPushButton(tr("Load"));
    backToMainMenuButton = new QPushButton(tr("Main Menu"));

    QObject::connect(backToMainMenuButton, SIGNAL(clicked()),
        this, SIGNAL(backToMainMenuClicked()));

    QVBoxLayout* layout = new QVBoxLayout();
    layout->addWidget(loadGameButton);
    layout->addWidget(backToMainMenuButton);
    layout->setContentsMargins(300, 400, 300, 200);
    setLayout(layout);
}

MainMenu.h:

#include <QtGui>

class MainMenu : public QWidget
{
    Q_OBJECT
public:
    MainMenu();
signals:
    void newGameClicked();
    void loadGameClicked();
private slots:
    void exit();
private:
    QPushButton* newGameButton;
    QPushButton* loadGameButton;
    QPushButton* exitGameButton;

    QMenu* fileMenu;
};

MainMenu.cpp:

#include "MainMenu.h"

MainMenu::MainMenu()
{
    newGameButton = new QPushButton(tr("New Game"), this);
    loadGameButton = new QPushButton(tr("Load Game"));
    exitGameButton = new QPushButton(tr("Exit"));

    QObject::connect(newGameButton, SIGNAL(clicked()), this, SIGNAL(newGameClicked()));
    QObject::connect(loadGameButton, SIGNAL(clicked()), this, SIGNAL(loadGameClicked()));
    QObject::connect(exitGameButton, SIGNAL(clicked()), qApp, SLOT(quit()));

    QVBoxLayout* layout = new QVBoxLayout();
    layout->addWidget(newGameButton);
    layout->addWidget(loadGameButton);
    layout->addWidget(exitGameButton);
    layout->setContentsMargins(300, 200, 300, 200);
    setLayout(layout);
}

void MainMenu::exit()
{
    if( QMessageBox::question(
        this,
        tr("Exit?"),
        tr("Do you really want to exit the game?"),
        QMessageBox::Yes | QMessageBox::No,
        QMessageBox::No
        ) == QMessageBox::Yes
    )
    {
        qApp->quit();
    }
}

main.cpp:

#include <QtGui>

#include "ApplicationWindow.h"

int main(int argv, char **args)
{
    QApplication app(argv, args);

    ApplicationWindow window;
    window.show();

    return app.exec();
}

Итак, как мне вызвать какое-либо поведение или действие, когда происходит переход?

Приветствие.

1 Ответ

2 голосов
/ 11 марта 2012

Чтобы действительно что-то сделать при переходе между состояниями, вы должны подключиться к сигналу triggered() перехода, например,

QAbstractTransition* trMainLoad = mainMenuState->addTransition(mainMenu, SIGNAL(loadGameClicked()), loadGameMenuState);
connect(trMainLoad , SIGNAL(triggered()), SLOT(...));
...