在类实例和另一个类实例中的对话框之间连接槽和信号

问题描述 投票:1回答:2

我正在QT编写一个程序,它目前有一个GameEngine(数据处理)类和一个MainWindow(GUI)类。

GameEngineand和MainWindow类的单个实例归int main函数所有。

MainWindow实例有一个User Action按钮,它将打开一个名为Dialog_UserAction的QDialog类的实例。 QDialog的实例由MainWindow拥有,MainWindow也是QDialog的父级(在Dialog_UserAction实例打开时禁用GameEngine GUI)。

我的问题是需要在QDialog和Dialog_UserAction实例之间连接许多事件(信号)。

有什么简单的方法可以达到这个目的吗?

我已经尝试过将GameEngine的信号通过MainBoard转发到Dialog_UserAction,反之亦然。这有效,但对于这项任务来说这是一个非常混乱的解决方案。

我也试过让MainUser Action Button clicked所有,但我不知道如何在主要背景下对Dialog_UserAction事件做出反应。

最后,我还尝试让GameEngineMainBoard实例拥有,这将是简单的解决方案(除了Dialog_UserAction GUI不会被禁用,而GameEngine被打开)。但是,我真的更喜欢所有与GUI相关的实例都不在class GameEngine : public QObject { Q_OBJECT signals: void someSignalToDialog(void); public slots: void on_someSignalFromDialog(); } 上下文中。

Gaminagineha:

class Dialog_UserAction: public QObject
{
    Q_OBJECT

signals:
    void someSignalToGameEngine(void);

public slots:
    void on_someSignalFromGameEngine();
}

Dialog_UserAction.h:

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    QApplication::setWindowIcon(QIcon(":/images/MageKnightLogo.jpg"));
    GameEngine gameEngine;
    Window_MainBoard mainBoard;

    mainBoard.showFullScreen();

    return a.exec();
}

Main.cpp的:

#include "Dialog_UserAction.h"

...

void Window_MainBoard::on_pushButton_enterUserAction_clicked() {
    Dialog_UserAction actionDialog(this);

    // connect signals and slots here?

    if (actionDialog.exec() == QDialog::Accepted)
    {
        // Send signal with data to GameEngine
    }
}
...

MainBoard.cpp:

Dialog_UserAction

所以,我真正要问的是:有没有简单的方法可以在这个设置中设置信号槽连接,我可以将GameEngineMainBoard连接,而无需转发GameEngine上下文中的信号?

如果没有,你对我如何以更好的方式处理这个问题有什么建议吗?提前致谢。

c++ qt hierarchy
2个回答
0
投票

由于Dialog_UserAction对象是单例(只存在一个实例),因此可以让GameEngine对象将其信号直接连接到Dialog_UserAction对象。你可以在GameEngine构造函数中做到这一点。

要轻松访问GameEngine*对象,只需向其中添加一个返回静态class GameEngine { public: GameEngine() { Q_ASSERT(instance_ == nullptr); // Only one instance allowed. instance_ = this; } static GameEngine* instance() noexcept { return instance_; } private: static GameEngine* instance_; }; 成员的静态成员函数。

Gaminagineha

GameEngine* GameEngine::instance_ = nullptr;

GameEngine.cpp

Dialog_UserAction

您现在可以将GameEngine::instance()信号连接到GameEngine::Instance()


0
投票

所以,为了澄清,我最终使用了Nikos C建议的Singleton设计模式。

但是我的课程实现方式略有不同,因此希望将其作为一个独立的答案分享。

我发现我需要以某种方式触发对象的构造函数,并认为这可以使用所谓的(我相信)Lazy Initialization方法来完成。此外,类的构造函数应该是私有的,这样只有实例本身才能调用它,从而确保构造函数只被调用一次。

此外,我将const static GameEngine*method作为class GameEngine { public: const static GameEngine* instance() { // Singleton instance reference getter if (instance_ == nullptr) instance_ = new GameEngine(); // This triggers the constructor of the object return instance_; } private: GameEngine(); // The constructor is made private! }; 类型,以便让对象的访问权限是只读的。

Gaminagineha

// Place this declaration in the top of the file to create the global class instance pointer
// The initial value of the pointer must be nullptr to let the constructor be correctly triggered at the first instance()-call
GameEngine* GameEngine::instance_ = nullptr;

GameEngine.cpp

Main

然后在Dialog_UserAction#include "GameEngine.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Window_MainBoard mainBoard; const GameEngine* gameEngine = GameEngine::instance(); // Const pointer to the Singleton instance of the GameEngine class (global object) QObject::connect(gameEngine, SIGNAL(someSignalToDialog), &mainBoard, SLOT(on_someSignalFromGameEngine)); } (客户端)中,通过在每个上下文中创建一个const类实例指针来使用对Singleton GameEngine实例的访问。

Main.cpp的

#include "GameEngine.h"

// Constructor
Dialog_UserAction::Dialog_UserAction(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog_UserAction) {
    ui->setupUi(this);

    // Const pointer to the Singleton instance of the GameEngine class (global object)
    const GameEngine* gameEngine = GameEngine::instance();

    connect(this, SIGNAL(someSignalToGameEngine), gameEngine, SLOT(on_someSignalFromDialog)                                                                );
}

Dialog_UserAction.cpp

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.