Qt+Creator快速入门-----第七章(Qt对象模型与容器类)学习总结
一、对象模型
1.信号和槽
信号和槽用于两个对象之间的通信。信号和槽机制是QT的核心特征,像wpf和winform中利用回调(callback)机制实现对象间的通信。(回调就是指向函数的指针,把这个指针传递给一个要被处理的函数,那么就可以在这个函数被处理时在适当的地方调用这个回调函数)
典型应用:将一个对话框中的值传递给另一个对话框
核心代码
//对话框1,头文件中 signals: void dlgReturn(int); // 自定义的信号 private slots: void on_pushButton_clicked(); //对话框1,cpp文件中 void MyDialog::on_pushButton_clicked() { int value = ui->spinBox->value(); // 获取输入的数值 emit dlgReturn(value); // 发射信号 close(); // 关闭对话框 }
//对话框2,头文件中 private slots: void showValue(int value); //对话框2,cpp文件中 MyDialog *dlg = new MyDialog(this); connect(dlg, &MyDialog::dlgReturn, this, &Widget::showValue); void Widget::showValue(int value) // 自定义槽 { ui->label->setText(tr("获取的值是:%1").arg(value)); }
信号和槽的注意事项
1.需要继承自QObject或其子类;
2.在类声明的最开始处添加Q_OBJECT宏
3.槽中参数的类型要和信号参数的类型相对应,且不能比信号的参数多
4.信号只用于声明,没有定义,且返回值为void类型
connect(const QObject *sender,const char* signal,const QObject *receiver,const char *method,Qt::ConnectionType type=Qt::AutoConnection)
connect()函数第四个参数事要执行的槽,该参数也可以指定一个信号,实现信号与信号的关联。
connect()函数最后一个参数type表明了关联的方式,默认Qt::AutoConnection,他表示在使用emit发射信号之后,就会执行槽,只有等槽执行完之后,才会执行emit语句后面的代码,如果改为Qt::QueuedConnection,执行完emit语句后便会立即执行其后面的代码,而不管槽是否已经执行完成。
// connect(dlg, &MyDialog::dlgReturn, [=](int value){ // ui->label->setText(tr("获取的值是:%1").arg(value)); // }); //labmbda表达式
使用自动关联的部件的定义都要放在setupUi()函数调用之前,而且必须使用setObjectName()指定它们的objectName,只有这样才能正常使用自动关联。
断开关联的几种方式
- disconnect(myObject,0,0,0)//断开与一个对象所有信号的关联
- disconnect(myObject,SIGNAL(mySignal()),0,0)//断开指定信号的关联
- disconnect(myObject,0,myReceiver,0)//断开指定信号的关联
- disconnect(myObject,SIGNAL(mySignal()),myReceiver,SLOT(mySlot()))//断开一个指定信号和槽的关联
信号和槽的特色和优越性:
1.信号和槽机制事类型安全的,相关联的信号和槽的参数必须匹配
2.信号和槽是松耦合的,信号发射者不需要知道接收者的信息
3.信号和槽可以用任意类型的任意数量的参数
回调机制缺陷:
不是类型安全的,不能保证在调用回调函数时可以使用正确的参数
强耦合,处理函数函数必须知道调用哪个回调函数。
2.属性系统
3.对象树和拥有权
父部件销毁时,会自动销毁它的所有子部件,这些都是Qt的对象树所完成的。所以规范的Qt程序,在main函数长将主窗体部件创建在栈上("Widget w"),而不是在堆上创建(使用new操作符),对于其他窗口部件,可以使用new操作符在堆上进行创建,不过一定要指定其父部件,这样就不需要使用delete操作符来进行销毁了。
4.元对象系统
二、容器类
顺序容器:QList(当数目小于1000时,可以实现列表中间进行快速的插入的操作,使用at()函数的读取比"[]"操作符要快很多)、QLinkedList、QVector、QStack和QQueue,数据是一个接一个线性存储的。
关联容器:QMap、QMultiMap、QHash、QMultiHash和QSet,存储的是<键,值>。
1.遍历容器
遍历容器可以使用迭代器(iterators)来完成,提供了一个统一的方法来访问容器中的项目,有java风格迭代器和STL风格迭代器,还有foreach关键字。
STL风格迭代器兼容QT和STL的通用算法,只读迭代器比读/写迭代器快。
在STL迭代器中"++"和"--"操作符既可以作为前缀,也可以作为后缀,当前缀时会先修改迭代器,然后返回迭代器的一个引用;当作为后缀时,在修改迭代器以前会对其进行复制,然后返回这个复制。如果在表达式中不会对返回值进行处理,那么最好使用前缀操作符,这样会更快。
2.通用算法
在<QtAlgorithms>头文件中,为Qt提供了一些全局的模板函数,这些函数可以使用在容器上的十分常用的算法,常用的有copy(),equal(),find(),fill(),count(),lower_bound(),sort(),greater()反向排序,swap().
<QtGlobal>头文件也提供一些函数来实现常用功能,如qAbs()函数获取绝对值,qMax(),qMin()函数返回两个数中的最大值和最小值。
3.QString
1)隐式共享又称为写时复制:减少内存使用和不必要的数据复制,因为只有一个指向该数据的指针被传递,分为深复制和浅复制,在一个对象被修改时必须进行一次深复制。
2)编辑操作
3)查询操作
4)转换操作
4.QByteArray和QVariant
三、正则表达式
Qt中的QRegExp类实现使用正则表达式进行模式匹配。QT5引入新的QRegularExpression类替代QRegExp。