使用QStateMachine在菜单屏幕之间切换 [英] Transitioning between menu screens with QStateMachine
问题描述
我正在考虑使用 QStateMachine
在菜单屏幕之间转换。然而,我不确定如何启动一些代码(例如 show()
a QWidget
状态发生。我可以很容易地用简单的老信号(见注释掉的代码),但我想我可以做一些花哨的动画切换屏幕使用过渡。
这里我的代码:
编辑:根据Koying的建议更新。
ApplicationWindow.h :
#include< QtGui>
#include< QStateMachine>
#includeMainMenu.h
#includeLoadGameMenu.h
类ApplicationWindow:public QMainWindow
{
Q_OBJECT
public:
ApplicationWindow();
私人插槽:
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: b
$ b
#include< QtGui>
class LoadGameMenu:public QWidget
{
Q_OBJECT
public:
LoadGameMenu();
signals:
void backToMainMenuClicked();
private:
QPushButton * loadGameButton;
QPushButton * backToMainMenuButton;
};
LoadGameMenu.cpp :
#includeLoadGameMenu.h
LoadGameMenu :: LoadGameMenu()
{
loadGameButton = new QPushButton (加载));
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: b
$ b
#include< QtGui>
class MainMenu:public QWidget
{
Q_OBJECT
public:
MainMenu();
signals:
void newGameClicked();
void loadGameClicked();
私有插槽:
void exit();
private:
QPushButton * newGameButton;
QPushButton * loadGameButton;
QPushButton * exitGameButton;
QMenu * fileMenu;
};
MainMenu.cpp :
#includeMainMenu.h
MainMenu :: MainMenu()
{
newGameButton = new QPushButton (新游戏),这);
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 ?),
tr(你真的想退出游戏吗?),
QMessageBox :: Yes | QMessageBox :: No,
QMessageBox :: No
) == QMessageBox :: Yes
)
{
qApp-> quit();
}
}
main.cpp:
#include< QtGui>
#includeApplicationWindow.h
int main(int argv,char ** args)
{
QApplication app(argv,args) ;
ApplicationWindow窗口;
window.show();
return app.exec();因此,当发生转换时,如何触发一些行为或操作? / p>
干杯。
解决方案您必须连接到转换的 triggered()
信号,例如
QAbstractTransition * trMainLoad = mainMenuState-> addTransition(mainMenu,SIGNAL(loadGameClicked()),loadGameMenuState);
connect(trMainLoad,SIGNAL(triggered()),SLOT(...));
I am considering transitioning between menu screens in a game by using QStateMachine
. However, I'm unsure how to kick off some code (e.g. show()
a QWidget
) upon a transition between states occurring. I can do it quite easily with plain old signals (see commented out code), but I figure that I could probably do some fancy animation upon switching screens using transitions.
Here's my code:
Edit: updated as per Koying's suggestion.
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();
}
So, how do I trigger some behaviour or action when a transition occurs?
Cheers.
解决方案 To actually do something on a state transition, you have to connect to the triggered()
signal of the transition, e.g.
QAbstractTransition* trMainLoad = mainMenuState->addTransition(mainMenu, SIGNAL(loadGameClicked()), loadGameMenuState);
connect(trMainLoad , SIGNAL(triggered()), SLOT(...));
这篇关于使用QStateMachine在菜单屏幕之间切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!