qt本身并不是一种编程语言,它实质上是一个跨平台的C++开发类库,是用标准C艹+编写的类库,它为开发GUI应用程序和非GUI应用程序提供了各种类。
qt对标准C艹+进行了扩展,引入了一些新的概念和功能,例如信号与槽、对象属性等。Qt的元对象编译器(Meta- Object Compiler,MoC)是一个预处理器,在源程序被编译前先将这些
qt特性的程序转换为标准C++兼容的形式,然后再由标准C艹+编译器进行编译。这就是为什么在使用信号与槽机制的类里,必须添加一个 Q_OBJECT宏的原因,只有添加了这个宏,moc才能对类里的信号与槽的代码进行预处理。
Qt Core模块是qt类库的核心,所有其他模块都依赖于此模块,如果使用 qmake来构建项目, Qt Core模块则是被自动加入的Qt为C+语言增加的特性就是在 Qt Core模块里实现的,这些扩展特性由Qt的元对象系统实现,包括信号与槽机制、属性系统、动态类型转换等。
在ui上布局完成后,需要构建工程才能索引出部件!
元对象系统由以下三个基础组成。
QObject类是所有使用元对象系统的类的基类在一个类的 private部分声明 Q OBJECT宏,使得类可以使用元对象的特性,如动态属性信号与槽。
MOC(元对象编译器)为每个 QObject的子类提供必要的代码来实现元对象系统的特性
qt使用信号与槽的机制实现对象间通信,它隐藏了复杂的底层实现,完成信号与槽的关联后,发射信号时并不需要知道Qt是如何找到槽函数的。Qt的信号与槽机制与 Delphi和C++ Builder的“事件—响应”比较类似,但是更加灵活。
某些开发架构使用回调函数( callback)实现对象间通信。与回调函数相比,信号与槽的执行速度稍微慢一点,因为需要査找连接的对象和槽函数,但是这种差别在应用程序运行时是感觉不到的,而其提供的灵活性却比回调函数强很多。
这是旧版写法。
connect(m_pBtn,SIGNAL(sigClicked()),this,SLOT(onClicked()));
connect(m_pBtn,&MyButton::sigClicked,this,&Widget::onClicked);
但是此方法只适用于信号名是唯一的时候,如果有重载编译会报错。
connect(m_pBtn, QOverload<bool>::of(&MyButton::sigClicked),this,&Widget::onClicked);
很显然这种写法相对于第二种会比较简单些,但依然不能连接到重载的槽函数,如果连接重载槽函数,还是会报之前的错误。
Lambda 函数写法
connect(m_pBtn, QOverload<bool>::of(&MyButton::sigClicked),
[=](bool check){
/* do something.. */
});
connect(m_pBtn, static_cast<void (MyButton::*)(bool)>(&MyButton::sigClicked), this, [=](bool check){
//do something
});
在自己设计的类里也可以自定义信号,信号就是在类定义里声明的一个函数,但是这个函数无需实现,只需发射(emit)。
例如,在下面的自定义类 PErson的 signals部分定义一个信号 age Changed(int)
class PErson: public Qobject
{
Q OBJECT
private:
int m age=l0;
public:
void incAge();
sgna⊥s:
void ageChanged(int value);
}
信号函数必须是无返回值的函数,但是可以有输入参数。信号函数无需实现,只需在某些条件下发射信号。例如,在 encAgeD函数中发射信号,其代码如下。
void Qperson::incAge()
{
m_age++;
emit ageChanged(m_age);
}
在 incAge函数里,当私有变量mage变化后,发射信号ageChanged(int),表示年龄发生了变化。至于是否有与此信号相关联的槽函数,信号发射者并不管。如果在使用 QPerson类对象的程序中为此信号关联了槽函数,在 encAged函数里发射此信号时,就会执行相关联的槽函数。至于是否立即执行槽函数,发射信号的线程是否等待槽函数执行完之后再执行后面的代码,与connecto函数设置信号与槽关联时设置的连接类型以及信号与槽是否在同一个线程有关。
private slots:
void on_ageChanged(int value);
``
## 元对象特性测试实例
```cpp
//PErson是 QObject的子类,在类定义部分使用了宏 Q OBJECT,这样 QPerson就获得了元对象系统支持,能使用信号与槽、属性等功能。
class QPerson : public QObject
{
Q_OBJECT
//PErson使用 Q CLASSINFO宏定义了3个附加信息,使用 Q PROPERTY宏定义了3个属性,还定义了一个信号。
Q_CLASSINFO("author","Wang")
Q_CLASSINFO("company","UPC")
Q_CLASSINFO("version","1.0.0")
Q_PROPERTY(int age READ age WRITE setAge NOTIFY ageChanged)
Q_PROPERTY(QString name MEMBER m_name)
Q_PROPERTY(int score MEMBER m_score)
private:
int m_age=10;
QString m_name;
int m_score=79;
public:
explicit QPerson(QString fName, QObject *parent = nullptr);
int age();
void setAge(int value);
void incAge();
signals:
void ageChanged( int value);
public slots:
};
略
参考链接:
https://library-cdq.oss-cn-beijing.aliyuncs.com/technology/Qt5.9 c%2B%2B开发指南.pdf
https://github.com/CdqPT/Qt5.9C-DevelopmentTutorialCode/tree/master/Source
原文:https://www.cnblogs.com/chendeqiang/p/12994489.html