Reputation: 45
I have a school project where I am using Qt to drive my GUI interface. I need to know the best way or the easiest way to transfer a vector of class objects between the different .cpp files for the different forms. I was thinking of including the .h files and making a setPointer and getPointer that points to the vector, but is there a better way?
Thanks for the help
Upvotes: 1
Views: 8887
Reputation: 11
Here is a simple explanation:
Take two forms:
Dialog windows Dashboard and Sensor
on Dashboard:
#ifndef DASHBOARD_H
#define DASHBOARD_H
#include "sensor.h"
#include <QDialog>
namespace Ui {
class dashboard;
}
class dashboard : public QDialog
{
Q_OBJECT
public:
explicit dashboard(QWidget *parent = 0);
QTimer *timer;
~dashboard();
public slots:
void MyTimerSlot();
private slots:
void on_pushButton_clicked();
private:
Ui::dashboard *ui;
double mTotal;
sensor *snsr;
};
#include "dashboard.h"
#include "ui_dashboard.h"
#include <QDebug>
#include <QTimer>
#include <QMessageBox>
dashboard::dashboard(QWidget *parent) :
QDialog(parent),
ui(new Ui::dashboard)
{
ui->setupUi(this);
this->setWindowTitle(QString("dashboard"));
// create a timer
timer = new QTimer(this);
// setup signal and slot
connect(timer, SIGNAL(timeout()),
this, SLOT(MyTimerSlot()));
timer->stop();
mTotal = 0;
snsr = new sensor(this);
// msecx
}
dashboard::~dashboard()
{
delete ui;
}
void dashboard::on_pushButton_clicked()
{
snsr->show();
}
void dashboard::MyTimerSlot()
{
mTotal += 1;
snsr->setValue(mTotal);
ui->sensorlabel->setText(QString::number(mTotal));
}
Now on Sensor: sensor.h
#ifndef SENSOR_H
#define SENSOR_H
#include <QTimer>
#include <QDialog>
namespace Ui {
class sensor;
}
class sensor : public QDialog
{
Q_OBJECT
public:
explicit sensor(QWidget *parent = 0);
~sensor();
public slots:
void setValue(double value);
signals:
void changeLabel();
void valueChanged(double newValue);
private:
Ui::sensor *ui;
double mTotal;
};
#endif // SENSOR_H
sensor.cpp
#include "sensor.h"
#include "ui_sensor.h"
#include "dashboard.h"
sensor::sensor(QWidget *parent) :
QDialog(parent),
ui(new Ui::sensor)
{
ui->setupUi(this);
this->setWindowTitle(QString("sensor"));
connect(this, SIGNAL(valueChanged(double)), this, SLOT(changeLabel()));
}
void sensor::changeLabel()
{
ui->sensorlabel->setText(QString::number(mTotal));
}
void sensor::setValue(double value)
{
if (value != mTotal) {
mTotal = value;
emit changeLabel();
}
}
sensor::~sensor()
{
delete ui;
}
Upvotes: 0
Reputation: 638
formA
and formB
.Create a signal and slot in forma.cpp
public slots: void receiveData(QVectorobjects);
signals: void sendData(QVector);
Do the same for formb.cpp
.
Now connect formA and formB like this.
connect(formA, SIGNAL(sendData(QVector<MyClass>)), formB, SLOT((receiveData(QVector<MyClass>)));
connect(formA, SIGNAL(receiveData(QVector<MyClass>)), formB, SLOT((MyClass(QVector<MyClass>)));
Now formA will share data (set of objects) when you write emit sendData(QVector() << objA << objB);
and formB will catch it!
Enjoy the magic of signal and slot. :)
Upvotes: 4
Reputation: 45
I ended up using the extern keyword. I looked in to custom signals and slots and I think that it would be the better way to go, but given time and the fact that this is for school I went with the fast and dirty way for now.
Upvotes: 0
Reputation: 3843
Use QVector or QList or any number of Qt's container classes. You can pass an iterator to your forms, or a reference (QList::operator[]) to the form so that you're not copying the data.
If you want to pass the whole vector, pass it as a reference. For example:
//pass the whole vector as for read-write
void doStuffOnMany(QList<MyClass>& listref) {} //declaration
...
QList<MyClass> mylist; //usage
doStuffOnMany(mylist);
//read-only
void doStuffOnMany(const QList<MyClass>& listref) {}
//pass one portion of the vector for read-write
void doStuffOnOne(MyClass& classref) {} //declaration
...
QList<MyClass> mylist; //usage
doStuffOnOne(mylist[0]);
Also, the Qt container classes are implicitly shared, so you don't even necessarily have to pass a reference to the vector if you need good performance.
Upvotes: 0
Reputation: 638
What about extern
keyword? But Qt's signal slot is safe.
Upvotes: 0
Reputation: 6524
Depending upon your usage, there can be at least two ways.
First is to create a public variable in your class (form) to which you can assign the current value of the vector (pointer) so that you can access it in that class.
Another option is to create a singleton class in the application and store the vector pointer inside that class. This will allow access to this class throughout the application.
Based on your requirement, if you want the vector to stay alive for the application life, you should opt the second option, otherwise opt the first option.
Upvotes: 0
Reputation: 5054
The best way to transfer data between Qt-classes is to use signal/slot system.
Pay an attention, that if you want to transfer data with type differ from standard C++ and Qt, you should register it's type with qRegisterMetaType
Upvotes: 0
Reputation: 49309
First of all, Qt container classes are implicitly shared, that means you can pass them by value, and only a shallow copy will occur. If you attempt to modify the container, then a new copy will be created. So there is no need to use pointers in that particular case.
Then, use signals and slot to do the actual data transfer - the common pattern is for the parent widget to manage its child widgets, and it is that parent class that the actual passing of data usually takes place.
Upvotes: 0
Reputation: 6594
You should use custom signals and slots. Your main window can connect signal and slot between each form.
In this way, you forms are independent of each other (i.e. doesn't need a pointer).
Upvotes: 1