Я рассматриваю переход между экранами меню в игре с помощью QStateMachine
. Тем не менее, я не уверен, как запустить код (например, show()
a QWidget
) при переходе между состояниями. Я могу сделать это довольно легко с помощью простых старых сигналов (см. Код с комментариями), но я полагаю, что, возможно, я мог бы сделать какую-нибудь причудливую анимацию при переключении экранов с использованием переходов.Переход между экранами меню с помощью QStateMachine
Вот мой код:
Edit: обновлены согласно предложению Koying в.
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();
}
Итак, как я могу вызвать какое-либо поведение или действие при переходе?
Cheers.
Cheers. Я сделал это, но теперь я получаю: «Необработанное исключение в 0x779815de (ntdll.dll) в Hello Notepad.exe: 0xC0000005: Доступ к чтению с ошибкой 0xabababaf.' Исключение происходит внутри' mainMenuButtonClicked() '- am I не предполагается дважды вызывать 'setCentralWidget'? Я обновил свой оригинальный пост своим новым кодом. – Mitch
В соответствии с 'setCentralWidget()' doc: 'QMainWindow берет на себя ответственность за указатель виджета и удаляет его в соответствующее время. ', Поэтому ваш mainMenu, вероятно, будет уничтожен, когда вы выполните' setCentralWidget (loadGameMenu); ' – Koying
Не подходит когда нет ссылок на указатель слева? Как еще я могу показать разные 'Виджеты' (экраны) внутри' QMainWindow'? Я делаю это только из-за неопытности - я открыт для других вариантов. – Mitch