У меня есть программа, которая (помимо прочего) имеет интерфейс командной строки, который позволяет пользователю вводить строки, которые затем будут отправляться по сети. Проблема в том, что я не уверен, как подключить события, которые генерируются глубоко внутри GUI, к сетевому интерфейсу. Предположим, например, что моя иерархия классов GUI выглядит следующим образом:
GUI -> MainWindow -> CommandLineInterface -> EntryField
Каждый объект GUI содержит некоторые другие объекты GUI, и все является частным. Теперь объект entryField генерирует событие / сигнал о том, что сообщение было введено. В данный момент я передаю сигнал вверх по иерархии классов, чтобы класс CLI выглядел примерно так:
public:
sig::csignal<void, string> msgEntered;
А в ctor:
entryField.msgEntered.connect(sigc::mem_fun(this, &CLI::passUp));
Функция passUp просто снова подает сигнал для класса-владельца (MainWindow), к которому нужно подключиться, пока я наконец не смогу сделать это в основном цикле:
gui.msgEntered.connect(sigc::mem_fun(networkInterface, &NetworkInterface::sendMSG));
Теперь это похоже на очень плохое решение. Каждый раз, когда я добавляю что-то в графический интерфейс, мне нужно подключить его по всей иерархии классов. Я вижу несколько способов обойти это. Я мог бы сделать все объекты общедоступными, что позволило бы мне сделать это в основном цикле:
gui.mainWindow.cli.entryField.msgEntered.connect(sigc::mem_fun(networkInterface, &NetworkInterface::sendMSG));
Но это противоречило бы идее инкапсуляции. Я мог бы также передать ссылку на сетевой интерфейс по всему графическому интерфейсу, но я хотел бы сохранить код графического интерфейса как можно более отдельным.
Такое ощущение, что я здесь упускаю что-то важное. Есть ли чистый способ сделать это?
Примечание: Я использую GTK + / gtkmm / LibSigC ++, но я не отмечаю его как таковой, потому что у меня была почти такая же проблема с Qt. Это действительно общий вопрос.