Как хранить глобальные данные в QList

Можете ли вы объяснить методы хранения данных программы с глобальным доступом?

Я нашел следующие ключевые слова:
– использование статического класса для хранения данных
– передача QList по значению
– передача Qlist по ссылке
– использование ключевого слова «друг»

но я не могу найти ни одного реального примера хранения глобального QList, как говорится, это плохой дизайн для использования глобальных переменных. Также упоминается, что использование указателей в QList — плохая идея из-за неявного совместного использования (?).

Итак, где я должен хранить свой Qlist для доступа к нему из другого класса в другом .cpp? Так что я:

главное окно.h

QList <SceneCard> sceneList;
QString mTitle;

public slots:
QString setValue()
    {
       return mTitle;
    }

главное окно.cpp

MainWindow::AddScene()
{
    sceneCard = new SceneCard(sNumber);
    sceneList.append(sceneCard);
    mTitle = "Nejat is right!"

}

void MainWindow::showSceneCard()
{
    SceneDialog D;
    connect(D,SIGNAL(getValue()),this,SLOT(setValue()));
    D.exec();
}

сценадиалог.h

#ifndef SCENEDIALOG_H
#define SCENEDIALOG_H

#include <QDialog>
#include <QList>

namespace Ui {
class SceneDialog;
}

class SceneDialog : public QDialog
{
    Q_OBJECT

public:
    SceneDialog(QWidget *parent = 0);
    ~SceneDialog();

signals:
    QString getValue();

private:
    Ui::SceneDialog *ui;
    QString myText;
};

сценадиалог.cpp

#include "scenedialog.h"
#include "ui_scenedialog.h"
#include <QDebug>

SceneDialog::SceneDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::SceneDialog)
{
    ui->setupUi(this);

    myText = getValue();
    qDebug() << myText; // myText is empty!!

}

person Dennis S    schedule 16.09.2014    source источник
comment
Вы должны быть знакомы с концепцией синглтона. Создайте одноэлементный класс, содержащий элемент QList. См. en.wikipedia.org/wiki/Singleton_pattern для получения дополнительной информации об этом шаблоне.   -  person bkausbk    schedule 16.09.2014
comment
Что вы имеете в виду под магазином? Наличие функции-члена, которая возвращает список, делает сделку? Отправка сигнала со списком тоже не работает?   -  person UmNyobe    schedule 16.09.2014
comment
«Хранить» означает, что мне нужно читать/записывать этот QList из разных файлов .cpp. Список должен быть доступен глобально.   -  person Dennis S    schedule 16.09.2014
comment
Хорошо, может быть, я должен перефразировать: у меня есть визуальные узлы в главном окне, и я вызываю диалог для редактирования их свойств. Затем я должен передать свойства всех узлов другому QWidgetTab   -  person Dennis S    schedule 16.09.2014
comment
Поэтому передайте необходимые данные в свой диалог, и когда диалог будет закрыт, приняв его, получите новые данные из диалога. Я не понимаю, зачем вам нужен глобальный QList для этого.   -  person thuga    schedule 16.09.2014
comment
Но мне нужно где-то хранить данные, прежде чем передавать их в диалог?   -  person Dennis S    schedule 16.09.2014
comment
Держите его где-нибудь в переменной-члене. Где вы создаете данные в первую очередь?   -  person thuga    schedule 16.09.2014
comment
@thuga В главном окне см. редактирование   -  person Dennis S    schedule 16.09.2014
comment
Ну вот, вы уже где-то храните данные. Теперь просто создайте функцию в вашем SceneDialog, которая принимает QList<SceneCard*> в качестве параметра, и передайте ей sceneList. Кстати, вроде должно быть QList<SceneCard*> в вашем mainwindow.h.   -  person thuga    schedule 16.09.2014
comment
@thuga Низкий вам поклон!   -  person Dennis S    schedule 16.09.2014


Ответы (1)


Вы можете поместить свой список в качестве члена класса и использовать механизм Qt Signal/slot для доступа к списку из других классов. Просто создайте сигнал в целевом классе, подключите его к слоту в классе, содержащем список, и установите связь между двумя объектами классов. Таким образом, вы можете получить доступ к любому члену данных других классов, подключив сигнал к слоту, возвращающему это значение, просто испустив сигнал и получив возвращаемое значение.

Например, если у вас есть два класса, например:

class A: public QObject
{
Q_OBJECT
public:
    A(QObject *parent = 0);
    ~A();

signals:
      int getValue();

private:

      void someFunction()
      {
           int val = getValue();
      }
};

class B 
{
Q_OBJECT
public:
    B(QObject *parent = 0);
    ~B();

public slots:

      int getValue()
      {
           return someValue;
      }
};

И подключите сигнал от объекта A к слоту в объекте B :

connect(a, SIGNAL(getValue()), b, SLOT(getValue()));

В классе A вы можете получить доступ к значению, возвращенному из слота getValue в B, просто вызвав сигнал и используя возвращенное значение.

Обратите внимание, что для этого два объекта должны находиться в одном потоке. Если они находятся в разных потоках, то тип соединения должен быть типа Qt::BlockingQueuedConnection :

connect(a, SIGNAL(getValue()), b, SLOT(getValue()), Qt::BlockingQueuedConnection);

Другой способ - использовать статические члены класса, но это не рекомендуется, если у вас нет веской причины для этого. Если у вас есть два класса, например:

class A {
   public:
      static QList<int> list;
};

class B {
   public:
      void do_something();
};

Вы можете получить доступ к статическому члену данных A из B следующим образом:

void B::do_something()
{
     int val = A::list[0];
     ...
};
person Nejat    schedule 16.09.2014
comment
Угу.. спасибо! Так что это просто: «класс myList: public QList {}»? - person Dennis S; 16.09.2014
comment
@DensiTensy Вероятно, вы не хотите создавать подкласс QList. - person thuga; 16.09.2014
comment
@DensiTensy Как вы пришли к выводу из ответа, что вам следует создать подкласс QList ?! - person Nejat; 16.09.2014
comment
@Nejat, я нуб! Итак, я ошибочно принял «член класса» за подкласс. Итак, list в классе A является членом класса? - person Dennis S; 16.09.2014
comment
Да. Это статический член класса, к которому можно получить глобальный доступ, добавив префикс имени класса. - person Nejat; 16.09.2014
comment
@Nejat, не могли бы вы опубликовать пример связи между классами? Я читал документы, там ничего не говорится о возвращаемых значениях слота. - person Dennis S; 27.09.2014
comment
@Nejat Я следовал вашим инструкциям, но myText не действует. Что не так, теперь это должно быть mTitle? - person Dennis S; 28.09.2014
comment
Это потому, что я подключаюсь после создания своего диалога? Если да, то как Dialog должен получать значения, если не в своем конструкторе? - person Dennis S; 28.09.2014
comment
Ага. Сначала вызывается конструктор перед подключением. Вы можете подать сигнал getValue() в showEvent диалогового окна. Также при подключении следует использовать адрес диалога: connect(&D,SIGNAL(getValue()),this,SLOT(setValue())); - person Nejat; 28.09.2014