C++ GTKMM gui 循环依赖

C++ GTKMM gui circular dependencies

我一直在尝试用 C++ 编写 GTKMM gui 应用程序。在我早期在 Java 的项目中,我开始制作所谓的 'Screen' 对象,每个对象都包含不同屏幕的布局和对象。所以我也在 C++ 中尝试过,我从 Gtk::Box 派生了这些不同的 Screen 对象,这样我就可以轻松地将它们附加到 Gtk::Notebook.

但是我发现这种方法会导致循环依赖,并且在大量浏览之后我找不到其他方法的人。我目前有一个屏幕可以显示从数据库中检索到的数据,并想为其添加过滤器。

我设法通过为每个屏幕提供指向它们所在 Gtk::Notebook 的指针来允许交换屏幕,但是当我无法弄清楚如何使两个屏幕相互交互时,我遇到了障碍其他(例如,在另一个屏幕中过滤数据)。

一般问题是这样的:

Gui.h:

class Gui {
protected:
    //  Child object pointers.
    Gtk::Notebook *m_screens;
    DbConnector *m_db;

    //  Screen object pointers.
    MainScreen *m_mainScreen;
    FilterScreen *m_filterScreen;
public:
    //  Constructors & destructor.
    Gui();
    virtual ~Gui();
};

Gui.cpp:

Gui::Gui() {
    //  Create application.
    auto app = Gtk::Application::create();

    //  Db connector
    m_db = new DbConnector();

    //  Create & configure window.
    Gtk::Window m_window;
    //  Window configs.....

    //  Create notebook & screen objects.
    m_screens = new Gtk::Notebook();
    m_screens->set_show_tabs(false);
    m_mainScreen = new MainScreen(*m_screens);
    m_filterScreen = new FilterScreen(*m_screens);

    //  Add notebook to window.
    m_window.add(*m_screens);

    //Insert pages.
    m_screens->append_page(*m_mainScreen);
    m_screens->append_page(*m_filterScreen);

    //  Show all children & run app.
    m_window.show_all_children();
    app->run(m_window);
}

MainScreen.h:

class MainScreen : public Gtk::Box {
protected:
    //  Parent notebook pointer.
    Gtk::Notebook* parent;

    //  Child widgets.
    Gtk::Button m_toFilterScreenButton = Gtk::Button("To Filter Screen");

    //  Constructors & desctructor.
    MainScreen(Gtk::Notebook& par);
    virtual ~MainScreen();

    //  Methods.
    void addFilter(std::string filterText);
    void toFilterScreen();
};

MainScreen.cpp:

MainScreen::MainScreen(Gtk::Notebook& par) : parent(&par) {
    //  Build screen.
    //  Packing contents.....

    //  Configure widgets.
    //  Things like widget border width.....

    //  Signal handlers.
    m_toFilterScreenButton.signal_clicked().connect(sigc::mem_fun(*this, &MainScreen::toFilterScreen));
}

void MainScreen::addFilter(std::string filterText) {
    //  Add filter
}

void MainScreen::toFilterScreen() {
    notebook->set_current_screen(pagenum_of_filterscreen);
}

我 运行 现在遇到的问题是当 FilterScreen 启动时,选择了一个过滤器,并且该过滤器应该应用于 MainScreenFilterScreen 无法通过 Gui 对象到达 MainScreen,因为这需要屏幕包含 Gui.h,这会导致循环依赖。尝试从 Gtk::Notebook returns 检索 MainScreen a Widget&,这将告诉您 Gtk::Widget 没有名为 addFilter(std::string filterText); 的函数。

是否有人知道我可以使用允许此类行为的模式?到目前为止,我能想到的唯一选择是一个巨大的 class,它使用函数而不是预制对象来设置屏幕,这远非最佳...

根据Sam Varshavchik in the comments I made a tiny example app that can handle multiple screens and switch easily. For those interested: source can be found here: ExampleApp

的建议