简体   繁体   English

C++ GTKMM gui 循环依赖

[英]C++ GTKMM gui circular dependencies

I have been attempting to write a GTKMM gui application in C++.我一直在尝试用 C++ 编写一个 GTKMM gui 应用程序。 In my earlier projects in Java I started by making so-called 'Screen' objects which would each contain the layout of, and objects in, different screens.在我早期的 Java 项目中,我开始制作所谓的“屏幕”对象,每个对象都包含不同屏幕的布局和对象。 So I tried that in C++ as well, I derived these different Screen objects from the Gtk::Box so that I could easily append them to a Gtk::Notebook .所以我也在 C++ 中尝试过,我从Gtk::Box派生了这些不同的 Screen 对象,以便我可以轻松地将它们附加到Gtk::Notebook

However I found out that this approach results in circular dependencies, and after a lot of browsing I couldn't find people with other approaches.但是我发现这种方法会导致循环依赖,经过大量浏览后,我找不到其他方法的人。 I currently have a screen to display data retrieved from a database, and wanted to add filters to that.我目前有一个屏幕来显示从数据库中检索到的数据,并希望为其添加过滤器。

I managed to allow the swapping of screens by giving each screen a pointer to the Gtk::Notebook they are in, but I hit a roadblock when I couldn't figure out how to make two screens interact with each other (eg. filter the data in another screen).我设法通过给每个屏幕一个指向它们所在的Gtk::Notebook的指针来允许屏幕交换,但是当我无法弄清楚如何使两个屏幕相互交互时(例如过滤另一个屏幕中的数据)。

The general problem appears like this:一般的问题是这样的:

Gui.h:贵.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.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:主屏幕.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:主屏幕.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);
}

The problem I ran into now is when the FilterScreen is up, a filter is selected, and that filter should be applied to the MainScreen .我现在遇到的问题是当FilterScreen启动时,选择了一个过滤器,并且该过滤器应该应用于MainScreen The FilterScreen can't reach the MainScreen via the Gui object because that would require the screens to include Gui.h , which would result in a circular dependency. FilterScreen无法通过Gui对象到达MainScreen ,因为这需要屏幕包含Gui.h ,这将导致循环依赖。 Trying to retrieve the MainScreen from the Gtk::Notebook returns a Widget& , which will tell you a Gtk::Widget has no function called addFilter(std::string filterText);尝试从Gtk::Notebook检索MainScreen返回一个Widget& ,它会告诉您Gtk::Widget没有名为addFilter(std::string filterText);函数addFilter(std::string filterText); . .

Is anybody aware of a pattern I could use that would allow this type of behavior?有没有人知道我可以使用的模式允许这种行为? So far the only option I can think of is one giant class that sets the screens using functions instead of premade objects, which would be far from optimal...到目前为止,我能想到的唯一选择是一个巨大的类,它使用函数而不是预制对象来设置屏幕,这远非最佳......

With the advice given by Sam Varshavchik in the comments I made a tiny example app that can handle multiple screens and switch easily.根据Sam Varshavchik在评论中给出的建议,我制作了一个可以处理多个屏幕并轻松切换的小示例应用程序。 For those interested: source can be found here: ExampleApp对于那些感兴趣的人:可以在这里找到源代码: ExampleApp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM