@VerNika

Qt. Как передавать данные между формами?

Имеется основная форма:
class MainWindow
{
    ...
private:
    ...
    QList<Institution> institutions;
};

И вторая форма:
class AddItem
{
    ...
};

Вторая форма вызывается из первой:
void MainWindow::on_action_add_item_triggered()
{
    AddItem *form_2 = new AddItem(this);
    form_2->show();
}


Как можно передать QList<Institution> institutions во вторую форму, чтобы коллекцию можно было редактировать в ней?
  • Вопрос задан
  • 7379 просмотров
Решения вопроса 3
AtomKrieg
@AtomKrieg
Давай я поищу в Google за тебя
По неконстантной ссылке (или указателю):
class AddItem
{
    AddItem(MainWindow *parent, QList<Institution>& ins);
...
private:
QList<Institution>& parent_institutions;
};

Но вообще это плохая практика. Свою приватную переменную должен редактировать класс который ей владеет. Для этого нужны свои методы - MainWindow::AddInstitution, MainWindow::RemoveInstitution, etc. Так как это у вас QT, то тут надо использовать слоты и сигналы.
Ответ написан
Комментировать
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
На самом деле вам не нужно ничего и никуда передавать, как мне кажется. Т.к. вторая форма используется только для создания новых элементов. Но обо всём по порядку. В приведённом фрагменте кода я вижу несколько архитектурных проблем (если не интересно, можете игнорироваться все, кроме пункта 3):
1) Вторая форма создаётся каждый раз, когда пользователь кликает на кнопку add_item. Это утечка памяти, т.к. все формы будут удалены только после удаления главного окна, но не ранее. Почему бы не создать форму один раз и просто её не показывать на действие? Создали в классе поле QScopedPointer m_addItemDlg (ну или std::unique_ptr), один раз выделили память в конструкторе и радуетесь жизни.
2) Это не очень хорошо, что Institution хранится в контейнере QList по значению т.к., скорее всего вы не реализовали семантику перемещения и всё это копируется... Хотя бы по этой причине (и по многим другим) стоит подумать о том, чтобы хранить все элементы как shared_ptr.
3) Наконец-то мы добрались и до вашего вопроса! В Qt есть отличный механизм слотов и сигналов. В вашем случае идея проста: у главной формы надо реализовать слот onInstitutionAdded а у второй формы дописать сигнал institutionAdded и соединить их в конструкторе главной формы. Когда новый объект создан выслать сигнал из второй формы и в слоте главного окна реализовать добавление в коллецию.
Если же нужно будет редактировать какой-то итем в коллекции, то его конечно лучше передать просто по ссылке перед тем как показать форму. Ну и в этом случае посмотреть уже в сторону Qt model-view.
4) Название класса второй формы слишком общее и ни о чем не говорит.
Ответ написан
@Mercury13
Программист на «си с крестами» и не только
Вариантов много, в зависимости от того, форма модальная или нет, и нужно ли каким-то моделям передавать сообщение «обновись».

Вариант 1.
class AddItem : public QWidget
{
public:
  AddItem(QWidget* aParent, QList<Institution>& aInstitutions)
      : QWidget(aParent), institutions(aInstitutions) {}
private:
  QList<Institution>& institutions;
};


Во втором варианте у нас модальная форма, но редактировать можно только копию (например, институции первой формы задействованы в какой-то модели, или нужны каскадные удаления, или что-то ещё).
class AddItem : public QDialog
{
public:
  int exec(QList<Institution>& aInstitutions);
private:
  QList<Institution> institutions;
};

int AddItem::exec(QList<Institution>& aInstitutions)
{
  institutions = aInstitutions;
  int r = QDialog::exec();
  if (r) {
     aInstitutions = std::move(institutions);
  }
  return r;
}


И много-много других вариантов.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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