元对象系统
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SOhlTZkRjY0kTMjhTO0QjM2MmZhZGM0YmZiJzYyQGNk9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
属性系统、信号与槽
目的是在元对象中通过MetaObject来访问
1、必须有一个是read函数,用来读取属性值。使用Const限定
2、可选Write函数 返回值必须为void,必须有一个参数
3、reset函数是将property设置为默认状态,返回值void,不带参数
4、NOTIFY信号,值改变会触发
5、STODE 一直存在
6、DESIGNABLE 属性表明在GUI builder中一直可见
7、USER 用户是否可修改
8、CONST 是否可修改,不能跟WRITE和NOTIFY同时出现
9、FINAL属性不会再派生类重写
在槽函数中,应该是知道sender对象的
案例
//QPerson.h
#define QPERSON_H
#include <QObject>
class QPerson : public QObject
{
Q_OBJECT
Q_CLASSINFO("author","QS")
Q_CLASSINFO("company","LXS")
Q_CLASSINFO("Version","1.0.0")
Q_PROPERTY(unsigned age READ age WRITE setAge NOTIFY ageChanged)
Q_PROPERTY(QString name MEMBER _name)
Q_PROPERTY(int score MEMBER _score)//添加属性,元数据可以访问
private:
unsigned _age = 10;
QString _name ;
int _score=79;
public:
explicit QPerson(QString name,QObject *parent = nullptr);
unsigned age();
void setAge(unsigned value);
void incAge();
signals:
ageChanged(unsigned value);
public slots:
};
#endif // QPERSON_H
//QPerson.cpp
#include "qperson.h"
QPerson::QPerson(QString name ,QObject *parent) : QObject(parent)
{
this->_name = name;
}
unsigned QPerson::age()
{
return _age;
}
void QPerson::setAge(unsigned value)
{
_age = value;
emit(ageChanged(value));
}
void QPerson::incAge()
{
_age++;
emit(ageChanged(_age));
}
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "qperson.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
QPerson * boy;
QPerson * girl;
private slots:
void on_btnBoyInc_clicked();
void on_btnGirlInc_clicked();
void on_btnMetaInfo_clicked();
void onspin_valueChanged(int value);
void onageChanged(unsigned value);
};
#endif // WIDGET_H
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QMetaProperty>
#include <QMetaClassInfo>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
ui->spinBoxBoy->setProperty("isBoy",true);
ui->spinBoxGirl->setProperty("isBoy",false);
boy = new QPerson("王小明");
boy->setProperty("score",85);
boy->setProperty("age",10);
boy->setProperty("sex","Boy");
girl = new QPerson("小红");
girl->setProperty("score",85);
girl ->setProperty("age",10);
girl ->setProperty("sex","girl");
connect(boy,&QPerson::ageChanged,this,&Widget::onageChanged);
connect(girl,&QPerson::ageChanged,this,&Widget::onageChanged);
connect(ui->spinBoxBoy,SIGNAL(valueChanged(int)),this,SLOT(onspin_valueChanged(int)));
connect(ui->spinBoxGirl,SIGNAL(valueChanged(int)),this,SLOT(onspin_valueChanged(int)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::onspin_valueChanged(int value)
{
Q_UNUSED(value);//参数用不到,但是不想让他警告
QSpinBox* spinBox = qobject_cast<QSpinBox*>(sender());
if(spinBox->property("isBoy").toBool())
boy->setAge(spinBox->value());
else
girl->setAge(spinBox->value());
}
void Widget::onageChanged(unsigned value)
{
Q_UNUSED(value);
QPerson* per = qobject_cast<QPerson*>(sender());
QString name = per->property("name").toString();
QString sex = per->property("sex").toString();
unsigned age = per->age();
ui->txtEdit->appendPlainText(name+","+sex+","+QString::asprintf(",年龄=%d",age));
}
void Widget::on_btnBoyInc_clicked()
{
boy->incAge();
}
void Widget::on_btnGirlInc_clicked()
{
girl->incAge();
}
void Widget::on_btnMetaInfo_clicked()
{
const QMetaObject * meta = girl->metaObject();
ui->txtEdit->clear();
ui->txtEdit->appendPlainText("====元信息========");
ui->txtEdit->appendPlainText(QString("类名称:%1\n").arg(meta->className()));
ui->txtEdit->appendPlainText(QString("property"));
for(int i = meta->propertyOffset();i<meta->propertyCount();i++)
{
QMetaProperty prop=meta->property(i);
const char* propName = prop.name();
QString propValue = boy->property(propName).toString();
ui->txtEdit->appendPlainText(QString("属性名称:%1,属性值:%2").arg(propName).arg(propValue));
}
ui->txtEdit->appendPlainText(QString(""));
ui->txtEdit->appendPlainText(QString("classInfo"));
for(int i=meta->classInfoOffset();i<meta->classInfoCount();i++)
{
QMetaClassInfo info = meta->classInfo(i);
ui->txtEdit->appendPlainText(QString("Name=%1,value=%2").arg(info.name()).arg(info.value()));
}
}
全局定义
容器类
QList维护一个指针数组
QLinkedList链式列表,非连续,所以不能下表访问
QVector在连续的内容上保存
QStack继承自QVector
QQueue继承自QList
QSet不允许重复,查找快速
QMap<K,T>会按照Key的顺序存储
QMap<K,T>一个Key会关联多个值
QHash<K,T>存储无顺序,查询快
QMultiHash<K,T>可对应多个值
容器迭代
Java方式
STL方式
sizes又复制了一份map.values(2),(自己测试后,发现sizes改变后,map并没有改)
类库模块
基本模块