У меня есть программа, которая (среди прочего) имеет интерфейс командной строки, который позволяет пользователю вводить строки, которые затем будут отправлены по сети. Проблема в том, что я не уверен, как связать события, которые генерируются глубоко внутри графического интерфейса, с сетевым интерфейсом. Предположим, например, что моя иерархия классов GUI выглядит так:
Графический интерфейс -> MainWindow -> CommandLineInterface -> EntryField
Каждый объект графического интерфейса содержит некоторые другие объекты графического интерфейса, и все это является частным. Теперь объект entryField генерирует событие / сигнал о том, что сообщение было введено. В настоящий момент я передаю сигнал вверх по иерархии классов, поэтому класс CLI будет выглядеть примерно так:
public:
sig::csignal<void, string> msgEntered;
И в c'tor:
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. Это действительно общий вопрос.