Как правильно принимать и передавать данные между классами, реализующими части оконного интерфейса?
В общем, есть примерно такой код (упрощённо):
class MainWindow : public QWidget
{
Q_OBJECT
private:
..............................
QSplitter *splitter;
PhotoWorkArea *work_area;
..............................
}
MainWindow::MainWindow(QWidget *parent)
: QWidget{parent}
{
..............................
splitter = new QSplitter{this};
work_area = new PhotoWorkArea{splitter};
..............................
}
Я хочу чтобы из PhotoWorkArea можно было иметь прямой доступ к другим виджетам, которые включённы в MainWindow. Иными словами, мне нужно иметь прямой доступ из одного включённого в MainWindow объекта к другим.
Я пытался сделать PhotoWorkArea другом MainWindow и включить main_window.hpp в photo_work_area.hpp, но так как второй уже включён в первый, то получается взаимное включение, из-за чего всё ломается. Поэтому единственный вариант, который мне пришёл в голову, включить main_window.hpp в photo_work_area.cpp, и писать в каждом методе, в котором мне нужен доступ к родительскому (в иерархии QObject) MainWindow следующее:
MainWindow *main_window = qobject_cast<MainWindow*>(this->parentWidget()->parentWidget());
Всё это как-то костыльно и криво. Подскажите, как лучше реализовать задуманное? Я думаю, что такая проблема не нова, и многие с ней уже сталкивались. Но я не знаю как это можно загуглить.
Ответы (1 шт):
Пришёл к такому выводу. Если нужно из одних частей оконного интерфейса получать и передавать данные в другие части интерфейса, то лучше это делать через слоты MainWindow (или аналога). А вместо дублирования самих данных, создавать внутри классов, реализующих часть оконного интерфейса, поля-указатели на эти данные, и в конструкторе MainWindow передавать их через геттеры и сеттеры соответствующих классов.
PS: Но всё же есть более простой, а может быть и более правильный (в зависимсоти от архитектуры приложения), способ:
child.hpp
#ifndef CHILD_HPP
#define CHILD_HPP
class Parent;
class Child
{
private:
Parent *parent;
public:
Child(Parent *parent);
~Child() = default;
};
#endif // CHILD_HPP
child.cpp
#include "child.hpp"
#include "parent.hpp"
Child::Child(Parent *_parent) : parent(_parent)
{
parent->doNothing();
}
parent.hpp
#ifndef PARENT_HPP
#define PARENT_HPP
#include "child.hpp"
class Parent
{
friend class Child;
private:
void doNothing() {}
public:
Parent() = default;
~Parent() = default;
private:
Child child;
};
#endif // PARENT_HPP