Como Manipular uma Classe Qualquer?
-
Eu queria saber se ''e possivel manipular qualquer classe usando o Qt?
Quero fazer um metodo, que seja capaz de receber uma classe qualquer, onde seja possivel saber todos ou parte dos atributos de uma classe, se possivel identificar os tipos desses atributos...
Pensei em usar "templates" mas, a classe QObject nnao suporta templates, ao menos na versao 4.7 do Qt...
Me deem uma luz... :D
-
Bom dia,
Será um pouco complicado, pois se você pretende receber objetos de classes derivadas de QObject, você terá que recebê-los através de ponteiros, visto que QObject possui o construtor por cópia e o operador "=" declarados como privados, o que impossibilita a passagem por valores para métodos e/ou funções de objetos desta categoria. Acredito também que o não funcionamento de templates para QObject e derivados seja causado também pela característica citada anteriormente.
Qual o seu objetivo com este método? Visto que você manipulará objetos tão diferentes entre si, não seria melhor fazer versões especializadas do método para cada um dos tipos de objetos que pretende manipular?Até mais.
-
Cara, também estou procurando uma alternativa que faça exatamente o que você quer. Uma classe especializada em mapear objetos de c++ para entidades do banco de dados de forma que execute todas as operações de gerenciamento (criar, deletar, editar, consultar) automaticamente, o que também é conhecido como padrão de projeto DAO (data access object). Pesquisei bastante na internet e descobri sobre alguns projetos para C++ que prometem fazer isso, o que mais me interessou foi o "QxOrm":http://www.qxorm.com/qxorm_en/home.html (construído usando Qt) mas ainda não tive tempo de estudar esta ferramenta.
Outra alternativa é você tentar implementar o padrão DAO, o que é o que estou fazendo atualmente. Criei uma classe base chamada DAO que contém um QSqlDatabase (referência de acesso ao banco), QSqlQuery (para executar comandos). A partir desta classe eu derivo outras que são especializadas em fazer as operações de banco para determinada classe, como por exemplo CidadeDAO, que implementa os métodos criar, deletar, editar e encontrar. Porém esta abordagem está se mostrando altamente improdutiva, pois é preciso se codificar muito (comandos sql). Estou pensando bastante em estudar o qxorm, o que ainda me faz continuar usando a segunda abordagem está no fato de o desempenho e customização serem facilmente manipuláveis.
-
Eu consegui alguma coisa aqui... Quando eu faço um metodo assim:
@bool inserir(QObject meuObjeto)@
depois so usar os signals e Slots para trocar mensagens com os objetos...
eu estava comendo barriga aqui com isso, dai lembrei que fiz algo parecido, mas foi para fazer buscas..
vou fazer um exemplo aqui e te falo o resultado...
-
Você quer serializar o QObject para gravar num BLOB por exemplo?
Usamos aqui uma abordagem de serializar o objeto semelhante ao "protobuf":https://code.google.com/p/protobuf/) ou o "boost::serialization":http://www.boost.org/doc/libs/1_53_0/libs/serialization/doc/index.html) mas do nosso jeito aqui (por questões de dependências e performance).
-
Quando vc disse
bq. @bool inserir(QObject meuObjeto)@
me lembrei que usamos aqui um mecanismo para serializar o objeto: transformar a classe em um vetor de bytes. Aí usamos para transmitir (via socket). No seu caso, você poderia armazenar o objeto no banco de dados, numa coluna BLOB. Algo +- assim:
@
class Message : public Serializable
{
public:
virtual ~Message( void ) { }
inline Header & getHeader( void ) { return header; }
virtual bool Read( Reader & br );
virtual void Write(Writer & bw );private:
Header header;
};
@cada classe implementa os Read e Write escrevendo a sua estrutura. Mas aqui não usamos o Qt (estou tentando convencer a galera aqui :-) )
Acho que talvez, o QMetaObject forneça o que você quer fazer, +- assim:
@
class C1 : public QObject
{
Q_OBJECT
private:public:
explicit C1(QObject *parent = 0);QString campo1() const; //Tem que existir o método de leitura Q_PROPERTY(QString campo1 READ campo1) //Aqui vc declara a propriedade
};
@E depois vc pode enumerar as propriedades:
@
int main(int argc, char *argv[])
{
C1 *c1 = new C1();const QMetaObject* metaObject = c1->metaObject(); for(int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); ++i) qDebug() << QString::fromLatin1(metaObject->property(i).name());
}
@Vc poderia listar as propriedades, e mapear as propriedades para cada campo em uma tabela.
Dê uma olhada "aqui":http://qt-project.org/doc/qt-4.8/properties.html e "aqui":http://qt-project.org/doc/qt-4.8/qmetaobject.html
-
Sabendo o nome das properties, vc pode acessar via
@QVariant v = obj->property("nome")@
onde o valor é "encapsulado" no "QVariant":http://qt-project.org/doc/qt-4.8/qvariant.html.
Você pode usar o type() ou typeName() do QVariant para saber o tipo.
-
Consegui!!!
header da classe c1:
@#ifndef C1_H
#define C1_H#include <QObject>
class C1 : public QObject
{
Q_OBJECT
private:public:
explicit C1(QObject *parent = 0);QString campo1();//const; //Tem que existir o método de leitura int campo2(); Q_PROPERTY(QString campo1 READ campo1)//Aqui vc declara a propriedade Q_PROPERTY(int campo2 READ campo2)
private:
};
#endif // C1_H
@Meu cpp da classe c1
@#include "c1.h"C1::C1(QObject *parent) :
QObject(parent)
{
}QString C1::campo1()
{
return "Consegui";
}int C1::campo2()
{
return 1;
}@Meu main.c ficou assim:
@#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QMetaProperty>
#include <QObject>
#include <QVariant>
#include <c1.h>static void testeprint(QObject c1)
{
const QMetaObject metaObject = c1->metaObject();for(int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); ++i) { QVariant v = c1->property(metaObject->property(i).name()); qDebug() << QString::fromLatin1(metaObject->property(i).name())<<v.toString()<<v.type(); }
}
int main(int argc, char *argv[])
{
C1 *c1 = new C1;
testeprint(c1);
return 0;
}@resultado do qDebug() :
"campo1" "Consegui" QVariant::QString
"campo2" "1" QVariant::intObrigadoTioRoy, suas dicas ajudaram muito!