DAY_1:
概念解析:
1、信号和槽机制(signal&slot)
信号和槽机制用于完成界面操作的响应,是完成任意两个QT对象之间的通信机制。
1.1、信号与槽机制的连接方式
a、 一个信号可以与另一个信号相连
connect(Object1,SIGNAL(signal1),Object2,SIGNAL(sinal2));
b、同一信号可以与多个槽相连
connect(Object1,SIGNAL(signal2),Object2,SIGNAL(slot2));
connect(Object1,SIGNAL(signal2),Object2,SIGNAL(slot1));
c、同一个槽响应多个信号
connect(Object1,SIGNAL(signal1),Object2,SIGNAL(slot1));
connect(Object1,SIGNAL(signal2),Object2,SIGNAL(slot1));
一般形式
connect(Object1,SIGNAL(signal),Object2,SLOT(slot));
1.2、信号与槽机制的优点
(a)、类型安全
需要关联的信号和槽必须是等同的,即信号的参数类型和参数个数与接收该信号的槽的参数类型与参数个数相同,不过一个槽的参数个数可以少于信号的参数个数,但是缺少的参数必须是信号参数的最后一个或者几个参数。
(b)、松散耦合
激发信号的qt对象无需知道是哪个槽需要接收它发出的信号,它只需要做的是在适当的时机发送适当的信号就可以了,而并不需要关心信号有没有被接收到,更不需要知道哪个对象的哪个槽接收到了信号,同样对象的槽也不需要知道是哪些信号关联了自己,一旦关联的信号和操qt保证得到调用。
一个类若要支持信号与槽机制,就必须从QObject或者QObject的子类继承,qt信号和槽机制不支持对模板的使用。
1.3、信号与槽机制效率问题
信号与槽机制虽然在一定程度上增强了对象之间通信的灵活性,但是也在性能方面付出了一定地代价,通常,通过传递一个信号来调用槽函数将会比直接调用非虚函数要慢到10倍左右,原因如下:
(a)、需要定位接收信号的对象
(b)、安全的遍历所有关联(如果存在一个信号关联多个槽的情况)
(c)、编组/解组传递的参数
(d)、多线程时,信号可能需要排队
2、QT5的元对象系统
元对象系统提供了对象之间的通信机制(信号和槽)、运行时类型信息和动态属性支持。是标准C++的一个扩展。元对象系统同样不支持C++模板。
元对象系统主要基于以下三个事实:
(a)、基类QObject:任何需要使用元对象系统功能的类必须继承自QObject
(b)、Q_OBJECT宏:Q_OBJECT宏必须出现在类的私有声明区,用于启动元对象系统
(c)、元对象编译器:为QObject子类实现元对象特性提供必要的代码实现
3、布局管理器
先看一段代码,按照代码解析
QGridLayout *mainLayout=new QGridLayout(this);//(a)
mainLayout->addWidget(label1,0,0); //(b)
mainLayout->addWidget(label2,1,0);
mainLayout->addWidget(lineEdit,0,1);
mainLayout->addWidget(button,1,1);
setLayout(mainlayout); //(c)
(a)、创建一个网格布局管理器对象mainlayout,并用this指向父类
(b)、分别将控件对象label button lineEdit 置于该管理器中,也可以在创建布局管理器对象时不必指明父窗口
(c)、将布局管理器添加到对应的窗口部件对象中。
对于布局管理在后续的学习中,慢慢了解
4、实例(求圆的面积)
代码:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
class Dialog : public QDialog
{
Q_OBJECT//启动qt元对象系统
public:
Dialog(QWidget *parent = 0);
~Dialog();
private:
QLabel *label1,*label2;
QLineEdit *lineEdit;
QPushButton *button;
private slots:
void showArea();
};
#endif // DIALOG_H
#include "dialog.h"
#include <QGridLayout>
const static double PI=3.1416;
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
label1=new QLabel(this);
label1->setText(tr("请输入圆的半径: "));
lineEdit=new QLineEdit(this);
label2=new QLabel(this);
button=new QPushButton(this);
button->setText(tr("显示对应园的面积"));
QGridLayout *mainLayout=new QGridLayout(this);//用于布局管理器
mainLayout->addWidget(label1,0,0);
mainLayout->addWidget(label2,1,0);
mainLayout->addWidget(lineEdit,0,1);
mainLayout->addWidget(button,1,1);
connect(button,SIGNAL(clicked()),this,SLOT(showArea()));//信号槽机制
}
void Dialog::showArea()
{
bool ok;
QString tempStr;
QString valueStr=lineEdit->text();
int valueInt=valueStr.toInt(&ok);
double area=valueInt*valueInt*PI;
label2->setText(tempStr.setNum(area));
}
Dialog::~Dialog()
{
}
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}