如何将相同的Widget连接到多个QSignalMapper映射

时间:2012-03-12 01:12:22

标签: c++ qt menu mapping signals-slots

this question开始,我有一个菜单系统如下:

MainMenu > (Load Game button clicked) > LoadGameMenu
LoadGameMenu > (Back To Main Menu button clicked) > MainMenu
LoadGameMenu > (Load button clicked) > GameScreen

但是,当我点击“加载”按钮时,会显示MainMenu。这是我的代码:

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

    stack = new QStackedWidget(this);
    signalMapper = new QSignalMapper(this);

    mainMenu = new MainMenu(this);
    loadGameMenu = new LoadGameMenu(this);
    gameScreen = new GameScreen(this);

    stack->addWidget(mainMenu);
    stack->addWidget(loadGameMenu);
    stack->addWidget(gameScreen);

    connect(mainMenu, SIGNAL(loadGameClicked()), signalMapper, SLOT(map()));
    connect(loadGameMenu, SIGNAL(backToMainMenuClicked()), signalMapper, SLOT(map()));
    connect(loadGameMenu, SIGNAL(loadClicked()), signalMapper, SLOT(map()));

    signalMapper->setMapping(loadGameMenu, 0);
    signalMapper->setMapping(mainMenu, 1);
    signalMapper->setMapping(gameScreen, 2);

    connect(signalMapper, SIGNAL(mapped(int)), stack, SLOT(setCurrentIndex(int)));

    setCentralWidget(stack);
}

我知道我对信号映射做错了,但我不知道它是什么。

干杯。

2 个答案:

答案 0 :(得分:2)

1)QSignalMapperQObject* sender映射到(in​​t,string,QWidget *或QObject *)。由于您的“加载”和“返回主菜单”信号是从同一发件人对象发送的,因此它们将以相同的方式映射。解决方案是将不同按钮的clicked信号直接连接到映射器(而不是通过LoadGameMenu对象),因此发件人是不同的。

2)由于您使用的是QStackedWidget,我强烈考虑使用QWidget*的{​​{1}}映射,并连接到QSignalMapper。如果/当您添加更多菜单屏幕时,这将更容易维护,而不是试图跟上哪个QStackedWidget::setCurrentWidget索引是哪个小部件。在我看来,它还使代码中的内容更具可读性。

编辑:您似乎不了解int功能。我会看看文档以获得更好的想法。你在做什么是将第一个参数(发送者)映射到要发送的信号(第二个参数)。在原始代码中,您将setMapping映射到LoadGameMenu。每当信号从0发送到映射器时,LoadGameMenu都会被发送到stackedWidget :: setCurrentIndex` - 这就是为什么两个按钮都会将您返回到同一个地方。

答案 1 :(得分:1)

QSignalMapper依靠信号的发送者进行映射,并且您要连接loadGameMenu两次。

如果发件人为loadGameMenu,则始终显示索引0。

最好直接连接到loadGameMenu小部件内的按钮。