使用QStateMachine在菜单屏幕之间切换 [英] Transitioning between menu screens with QStateMachine

查看:1770
本文介绍了使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆