EgoRusMarch
@EgoRusMarch
C++ Developer

Как правильно принимать и передавать данные между классами, реализующими части оконного интерфейса?

В общем, есть примерно такой код (упрощённо):

Example:
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());

Всё это как-то костыльно и криво. Подскажите, как лучше реализовать задуманное? Я думаю, что такая проблема не нова, и многие с ней уже сталкивались. Но я не знаю как это можно загуглить.
  • Вопрос задан
  • 74 просмотра
Решения вопроса 1
EgoRusMarch
@EgoRusMarch Автор вопроса
C++ Developer
13.07.20
Пришёл к такому выводу. Если нужно из одних частей оконного интерфейса получать и передавать данные в другие части интерфейса, то лучше это делать через слоты MainWindow (или аналога). А вместо дублирования самих данных, создавать внутри классов, реализующих часть оконного интерфейса, поля-указатели на эти данные, и в конструкторе MainWindow передавать их через геттеры и сеттеры соответствующих классов.

14.07.20
Похоже я нашёл способ проще =)
main.cpp
#include "parent.hpp"

int main()
{
    Parent object;
    return 0;
}
parent.hpp
#ifndef PARENT_HPP
#define PARENT_HPP

#include "child.hpp"

class Parent
{
    friend class Child;

private:
    Child child{this};

public:
    Parent() = default;
    ~Parent() = default;

private:
    void doNothing() const;
};

#endif // PARENT_HPP
child.hpp
#ifndef CHILD_HPP
#define CHILD_HPP

class Parent;

class Child
{
private:
    Parent *parent;

public:
    Child(Parent *parent);
    ~Child() = default;
};

#endif // CHILD_HPP
parent.cpp
#include "parent.hpp"
#include <iostream>

void Parent::doNothing() const
{
    std::clog << "Do nothing!\n" << std::endl;
}
child.cpp
#include "child.hpp"
#include "parent.hpp"

Child::Child(Parent *_parent) : parent(_parent)
{
    parent->doNothing();
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы