¿Tener objeto visible en toda la aplicación?

Hola de nuevo:

¿Cómo se hace en Qt para que un objeto declarado en MainWindow sea visible para todo el resto del programa?

Me explico (o lo intento jeje) El proyecto que estoy haciendo es Multiusuario y Multiempresa y me interesa tener un objeto cuyas propiedades (ruta acceso a la BD de la empresa seleccionada, usuarioBDEmpresa, Password, Empresa activa, etc, etc....) sean visibles en todas las pantallas con el propósito de actuar de una u otra forma dependiendo del usuario, empresa, etc)

o sea, me interesa en Main que al seleccionar una empresa se guarde su id en el objeto configuración y luego al abrir por ejemplo la pantalla clientes poder evaluar el id de ese objeto configuración sin tener que crear otra instancia y que se pierdan los valores dados en Main, y de ese modo tener los valores para abrir una u otra base de datos dependiendo de la empresa.

He buscado en Google y no encuentro cómo se hace en Qt para tener esos objetos visibles para toda la aplicación. estoy convencido de que debe ser algo fácil pero no lo veo. Pegas de ser novato en Qt, snif,snif.

Gracias por vuestra ayuda.

puntero global

Hola

Se me ocurre que puedes declarar un puntero global a esa clase.

Saludos

gracias jc: Bueno, dándole

gracias jc:

Bueno, dándole vueltas pienso que tal vez lo mejor en Qt sea usar señales/slots para conseguir eso que quiero. Aunque tengo que aprender cómo usarlos (pegas de ser novato) pero creo que es lo suyo, pues si defino un objeto oConfiguracion en MainWindow éste estará siempre visible en MainWindow ¿no? por tanto con un sistema de señales/slots, desde cualquier lugar debería poder operar con oConfiguracion, para dar y obtener valores de ese objeto.

¿Estoy en lo cierto?, ¿es esa una buena forma en Qt?

Gracias.

Tienes muchisimas opciones

Puedes utilizar un patrón Singleton. Esto os va a encantar :D

// .H
 
class Singleton : public QObject
{
 Q_OBJECT
 
 public:
 
  static Singleton *getInstance(QObject *parent=0);
 
  //...
 
 private:
 
  static Singleton *instanciaUnica;
 
  explicit Singleton(QObject *parent=0);
}
 
//.CPP
 
Singleton *Singleton::instanciaUnica=0;
 
Singleton::Singleton(QObject *parent) :
  QObject(parent)
{
}
 
Singleton *Singleton::getInstance(QObject parent)
{
 if(!instancia)
    instancia=new Singleton(parent);
 
 return instancia;
}

Realmente, esto sería algo así como matar moscas a cañonazos; si el objeto que necesitas que sea accesible desde cualquier lugar de la aplicación sólo va a contener datos de configuración y no va a realizar ninguna otra tarea, puedes utilizar QSettings para guardar los datos en el registro de Windows o en un archivo .INI o en un XML de Mac, dependiendo de la plataforma. QSettings tiene la ventaja de ser transparente al usuario, de tal forma que simplemente con declarar el objeto él solito busca el método más adecuado para almacenar esos datos, y acceder a ellos es muy sencillo. Buscalo dentro de la documentación.

Otra opción que puedes emplear, si ese objeto tiene otras tareas aparte de guardar y ofrecer información, es la de hacer que todas las clases que tengan que hacer uso de él lo reciban como argumento en forma de puntero, y así poder emplear sus métodos y utilizarlo.

¡Un saludo!

Gracias, Er Bardo

Muy interesante lo del patrón Singleton, sin embargo creo que lo que me va a ir de perlas va a ser el QSettings. Voy a probar a ver si consigo lo deseado.

Esto de ser novato es un fastidio (y más aun cuando se viene con costumbres de otros lenguajes de programación). ¿Cómo le paso a un formulario .iu el objeto como puntero?, he probado a hacerlo de esta forma y no me deja ni compilar:

// en MainWindow cpp
void MainWindow::on_btnClientes_clicked()
{
    frmClientes *frmClientes1 = new frmClientes(Configuracion *oConfig);
    workspace->addWindow(frmClientes1);
........

// en frmClientes.cpp
Cliente *oCliente = new Cliente();
frmClientes::frmClientes(QWidget *parent,*oConfiguracion) :
    QDialog(parent),
    ui(new Ui::frmClientes)
{
    ui->setupUi(this);
.....

Aunque probablemente no me va a servir en esta ocasión me gustaría conocer la forma correcta de hacerlo, para futuras ocasiones.

¿ Acaso no se puede pasar el parámetro al constructor del formulario?

¿Me puedes indicar que burrada de novato estoy cometiendo?

Gracias

Singleton

Hola

Singletón lo he usado algunas veces al hacer pequeños videojuegos, ni se me había ocurrido aplicarlo a tu caso.

Para pasar un puntero a una clase primero tienes que declarar en el .h un puntero del tipo adecuado y luego el parámetro lo puedes pasar en el constructor, o, si el objeto que quieres pasar no estará disponible en el momento de crear la otra ventana, puedes crear un método para pasárselo, por ejemplo:

#ifndef DIALOG_H
#define DIALOG_H
 
#include <QDialog>
#include <tuclase.h>
 
extern ClaseGlobal *config;
 
namespace Ui {
class Dialog;
}
 
class Dialog : public QDialog
{
	Q_OBJECT
 
public:
        // en el constructor
	explicit Dialog(TuClase *pClase, QWidget *parent = 0);
	~Dialog();
 
        // método público para establecer el puntero
	void setPuntero(TuClase *pClase);
 
private:
	Ui::Dialog *ui;
	TuClase *pLocal; // puntero a la clase
};
 
#endif // DIALOG_H

y el .cpp:

// el constructor con el parámetro
Dialog::Dialog(ClaseGlobal *pClase, QWidget *parent): QDialog(parent), ui(new Ui::Dialog)
{
	ui->setupUi(this);
	pLocal = pClase;
}
 
// el método para establecer el puntero
void Dialog::setPuntero(ClaseGlobal *pClase)
{
	pLocal = pClase;
}

Luego, cuando creas la ventana:

Dialog ventana;
ventana.setPuntero(punteroATuClase); // usando el método para establecer el puntero
 
ventana.exec();

De esta forma, tienes que tener precaución en la clase que recibe el puntero de no usarlo antes de que lo hayas establecido mediante el método setPuntero;

O usando el constructor

Dialog ventana(punteroATuClase);
 
ventana.exec();

En cualquier caso, ten cuidado con la destrucción del objeto, si le has pasado el puntero a alguna clase y esta lo destruye, te dará un error si tratas de acceder al objeto desde otra parte.

Saludos

pasar objeto

O sea, que por lo que entiendo ¿hay que pasar el puntero a un método del formulario, en este caso setPuntero en lugar de pasarlo directamente al constructor de la clase del formulario.?

Perdonad que insista, pero es que como vengo de otros lenguajes (VFP, gambas, pascal, java.....) tengo costumbres adquiridas que me hacen volver un poco majareta en c++/Qt :-P

Re: pasar objeto

Hola

Lo que hacemos es pasar un puntero al objeto. El método setPuntero que puse en el ejemplo anterior es el que se encarga de pasar ese puntero.

También puedes hacerlo en el constructor, como puse en el ejemplo, como mejor te venga en tu programa.

La verdad que es un lío cuando se usan varios lenguajes de programación, ahora mismo estoy haciendo un pequeño juego en Java para Android, cuando termine y vuelva a mi proyecto de Qt + C++ tendré que repasar la documentación xD

Saludos

Resuelto, gracias

El problema lo tenía (supongo) en como pasaba el parámetro al constructor del form ya que yo lo pasaba como segundo parametro y veo que jc lo pone al principio.

Muchas gracias por vuestras respuestas. Todas ellas me han ayudado a comprender mejor C++ y Qt.

Anuncios Google