Search code examples
qtqlist

How to store global data in QList


Can you explain a methods for storing program data with global access ?

I found these keywords:
- using static class to store data
- pass QList by value
- pass Qlist by reference
- use 'friend' keyword

but I cannot find any real example of storing global QList, as they say, it is a bad design to use global variables. Also there is a mention that using pointers on a QList is a bad idea because of implicit sharing (?).

So where should I store my Qlist for accessing it from a different class in an other .cpp ? So I have:

mainwindow.h

QList <SceneCard> sceneList;
QString mTitle;

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

mainwindow.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();
}

scenedialog.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;
};

scenedialog.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!!

}

Solution

  • You can put your list as a class member and use Qt's Signal/slot mechanism to access the list from other classes. Just make a signal in the target class, connect it to a slot in the class containing the list and make a connection between two objects of the classes. This way you can access any data member of other classes by connecting a signal to a slot returning that value and just emitting the signal and getting the return value.

    For example if you have two classes like :

    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;
          }
    };
    

    And connect the signal from an object of A to the slot in an object of B :

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

    In class A you can access the value returned from getValue slot in B by just calling the signal and using the returned value.

    Note that the two objects should be in the same thread for this to work. If they are in different threads then the connection type should be of type Qt::BlockingQueuedConnection :

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

    Another way is two use static class members but it is not recommended unless you have a good reason to do it. If you have two classes like :

    class A {
       public:
          static QList<int> list;
    };
    
    class B {
       public:
          void do_something();
    };
    

    You can access A's static data member from B like this:

    void B::do_something()
    {
         int val = A::list[0];
         ...
    };