Я пытался написать приложение графического интерфейса GTKMM на C ++. В моих предыдущих проектах на Java я начинал с создания так называемых «экранных» объектов, каждый из которых содержал бы макеты и объекты на разных экранах. Итак, я попробовал это и в C ++, я получил эти различные объекты Screen из Gtk::Box
, чтобы я мог легко добавить их в 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
активен, выбран фильтр, и этот фильтр должен быть применен к MainScreen
. FilterScreen
не может достичь MainScreen
через объект Gui
, потому что для этого на экранах должно быть Gui.h
, что приведет к циклической зависимости. Попытка извлечь MainScreen
из Gtk::Notebook
возвращает Widget&
, который скажет вам, что Gtk::Widget
не имеет функции с именем addFilter(std::string filterText);
.
Кто-нибудь знает о шаблоне, который я мог бы использовать, который позволил бы этот тип поведения? Пока что я могу думать только об одном-единственном гигантском классе, который устанавливает экраны, используя функции вместо готовых объектов, что было бы далеко от оптимального ...