C ++ GTKMM gui循环依赖项

时间:2018-10-30 10:50:05

标签: c++ user-interface circular-dependency gtkmm

我一直试图用C ++编写GTKMM gui应用程序。在我早期的Java项目中,我首先制作了所谓的“屏幕”对象,每个对象都包含不同屏幕的布局和对象。因此,我也尝试在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无法通过MainScreen对象到达Gui,因为这将要求屏幕包含Gui.h,这将导致循环依赖。尝试从MainScreen中检索Gtk::Notebook会返回Widget&,这将告诉您Gtk::Widget没有名为addFilter(std::string filterText);的函数。

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

1 个答案:

答案 0 :(得分:0)

根据Sam Varshavchik在评论中的建议,我制作了一个微型示例应用程序,可以处理多个屏幕并轻松切换。对于那些感兴趣的人:可以在这里找到源:ExampleApp