1.QObject
QObject是绝大多数Qt类的基类, 也有些类不是继承的他
- 需要轻量级实现的类 如(QPoint QRect QColor QBrush...等)
- 数据容器 (QString QList QChar)
- 可拷贝的类.. PS:言外之意 QObject 系列都是不能 拷贝构造 或者赋值的,这种界面类复制一个确实很奇怪
2.Meta data
主要包含了
- 类名(QObject::className)
- 继承(QObject::inherits)
- 属性(QObject::properties)
- 信号和槽
- 类信息
今天主要学了 属性,属性就是 用一些宏,在来控制,在编译时收集获取的属性信息
Demo
valueobject.h
#ifndef VALUEOBJECT_H
#define VALUEOBJECT_H
#include <QObject>
#include <QDebug>
class ValueObject : public QObject
{
Q_OBJECT //编译时收集类信息
/*设置类信息的宏
*在程序中可以使用相应函数获取设置的信息
*/
Q_ENUMS(week) //PS: 枚举类型必须为公有
/*
Q_PROPERTY(type name
READ getFunction
[WRITE setFunction]
[RESET resetFunction]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool])
*/
Q_PROPERTY(int valueInt
READ value
WRITE setValue
)
public:
ValueObject(QObject* parent=0);
int value(void) const
{
return m_value;
}
~ValueObject();
enum week{A1,A2,A3} ;
public slots:
void setValue(int v)
{
if( v != m_value ) /*避免死循环*/
{
qDebug()<<this->objectName()<<"m_value "<<m_value<<"change to"<<v;
m_value = v;
emit valueChange(m_value);
}
}
private:
int m_value;
signals:
void valueChange(int v);
};
#endif // VALUEOBJECT_H
#include "valueobject.h"
ValueObject::ValueObject(QObject* parent):QObject(parent),m_value(0)
{
}
ValueObject::~ValueObject()
{
qDebug()<<this->objectName()<<" destruct";
}
#include <QtCore/QCoreApplication>
#include "valueobject.h"
#include <QDebug>
#include <QtCore>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ValueObject v;
bool ok = false;
QVariant s;
qDebug()<<v.inherits("QObject") /*检测是否具有继承关系*/
<<v.inherits("ValueObject");
int index = v.metaObject()->indexOfEnumerator("week"); /*获取类信息 [枚举类型列表]index 供 enumerator()索引*/
/*----------------------------------------------------------
* PS: Q_ENUMS连续设置多个 编号则0~n 用 enumerator(int index)
* 索引出 QMetaEnum 对象
* 然后 QMetaEnum().key(int index) 返回枚举相应名字符串指针
*---------------------------------------------------------*/
qDebug()<<(v.metaObject()->enumerator(index).key(1));
/*---------------------------------------------------------
* property("属性名") 调用 Q_PROPERTY 设置的 READ 函数
* setProperty("属性名",v) 调用 Q_PROPERTY 设置的 WRITE 函数
* 设置时类型不匹配返回 false
* 设置时诺属性不存在则返回 false 动态添加该属性
* PS:同样可以用 int index 进行索引, propertyCount() 返回属性
* 个数
*--------------------------------------------------------*/
qDebug()<<v.property("valueInt").toInt(&ok);
qDebug()<<ok;
v.setProperty("valueInt",777);
qDebug()<<v.property("valueInt").toInt(&ok);
qDebug()<<ok;
/*----------------------------------------------------------
* 测试父子对象内存管理
*---------------------------------------------------------*/
ValueObject* parent = new ValueObject();
parent->setObjectName("parent");
ValueObject* child1 = new ValueObject(parent);
child1->setObjectName("child1");
ValueObject* child2 = new ValueObject(parent);
child2->setObjectName("child2");
ValueObject* c1s_chiled1 = new ValueObject(child1);
c1s_chiled1->setObjectName("c1s_chiled1");
ValueObject* c1s_chiled2 = new ValueObject(child1);
c1s_chiled2->setObjectName("c1s_chiled2");
ValueObject* c2s_chiled1 = new ValueObject(child2);
c2s_chiled1->setObjectName("c2s_chiled1");
ValueObject c2s_chiled2(child2);
c2s_chiled2.setObjectName("c2s_chiled2");
delete parent;
/*
* 测试交互
*/
ValueObject s1,s2;
s1.setObjectName("s1");
s2.setObjectName("s2");
QObject::connect(&s1,SIGNAL(valueChange(int)), /*PS: connect 为 QObject 静态成员函数,非静态也有...*/
&s2,SLOT(setValue(int)));
s2.connect(&s2,SIGNAL(valueChange(int)),
&s1,SLOT(setValue(int)));
s1.setValue(7);
s2.setValue(17);
int ret = a.exec();
return ret;
}
Q_OBJECT
使用信号与槽的类在类的声明中都必须加上Q_OBJECT宏,表示使用元对象系统,Q_OBJECT列出元对象的声明、类名、属性函数、字符串翻译函数等。Q_OBJECT的宏定义列出如下(在src/kernel/qobjectdefs.h中):