Day04
Qt对象模型
信号和槽、对象属性系统、事件和事件过滤器、国际化翻译机制、定时器驱动、守卫指针(QPoint)、动态的对象转换机制(dynamic cast)
信号和槽
signals:声明一个信号使用signals,在signals前面不能使用public、private和protected等限定符,因为只有定义该信号的类和其子类能发射该信号
需要继承自QObject或其子类
在类声明最开始处添加Q_OBJECT
槽中的参数要和信号的参数类型相对应,不能比信号参数多。
信号只用声明,没有定义
容器类
容器类可以用来存储指定类型的项目,例如需要一个QString类型的可变大小的数组,那么可以使用QVector(QString)。
Qt提供了顺序容器(QList 、QLinkedList 、QVector、QStack、QQueue)关联容器(QMap、QMultiMap、QHash、QMultiHash和QSet),这些容器存储的是<键,值>,比如QMap<Key,T>。
QList<T>,目前最常用的容器类,他存储了给定类型的一个列表,而这些值可以通过索引访问。在内部,QList使用数组来实现,以确保进行快速的基于索引的访问。
QList::append() QList::prepend()
在列表俩端添加项目QList::insert()
在列表的中间插入项目。
QLinkedList<T>除了使用迭代器而不使用整数索引访问项目外,它基本与QList相同,当在一个很大列表中间插入项目其性能表现的更好。
QVector<T>它在内存相邻位置存储给定类型的值得一个数组,在vector中间插入项目是非常缓慢。
QStack<T>它是QVector一个便捷子类,提供了后进先出的语义,添加了push()、pop()、top()等函数
QQueue<T>它是QVector的便捷子类,通过了先进先出的语义,添加了enqueue()、dequeue()、和head()等函数
QMap<Key,T>它提供了一个字典,将Key类型的键值映射到T类型的值上,一般一个键关联一个值,QMap使用键顺序来存储他们,如果不关心顺序可以使用QHash来代替他
QMultiMap<Key,T>是QMap的一个便捷类,提供了多值映射的方便接口函数
QList
//插入项目
QList<QString> list; list << "aa" << "bb" << "cc"; list[3] = "ab"; list.append("dd"); list.prepend("mm"); list.insert(2,"mm");
//替换项目,交换项目
list.replace(2,"bc"); list.swap(1,3);
//删除项目
QString str = list.takeAt(2);
//包含项目,包含个数
list.contains("mm"); list.count("mm");
//查找项目,指定查找位置
list.indexOf("mm");//第一个“mm”的位置 list.indexOf("mm",1); list.at(i);
QMap
//插入项目
QMap<QString,int> map; map["one"] = 1; map.insert("seven",7);
//获取键的值
int value1 = map["six"];
//如果map中没有该键自动插入
int values = map.value("five");//不会自动插入
//一键多值
map.insertMulti("two",2); map.insertMulti("two",4); QList<int> values = map.values("two");
遍历容器
遍历一个容器可以使用迭代器来完成,迭代器提供了一个统一的方法来访问容器中的项目。Qt提供了二种风格的迭代器:Java风格迭代器和STL风格迭代器。按顺序遍历一遍容器中项目还可以使用Qt的foreach关键字
Java风格迭代器
容器 只读迭代器 读/写迭代器
QList<T> QListIterator<T> QMutableListIterator<T>
QLinkedList QLinkedListIterator<T> QMutableListIterator<T>
QListIterator<QString> i(list); //创建列表的只读迭代器 while(i.hasNext()) qDebug() << i.next(); while(i.hasPrevious()) qDebug() << i.previous();
-
toFront()
将迭代器移动到列表最前面 -
toBack()
将迭代器移动到列表最后面 -
hasNext()
如果跌倒器没有到达列表最后面返回true -
next()
返回下一个项目,并且使前移一个位置 -
peekNext()
返回下一个项目,但是不移动迭代器 -
hasPrevious()
如果迭代器没有到达最前面,那么返回true -
previous()
返回前一个项目,并且使迭代器前移一个位置 -
peekPrevious()
返回前一个项目,但是不移动迭代器
QMutableListIterator
这个类增加了insert(),remove(),setValue,来完成插入,删除,设置值
-
remove()
删除上一次跳过的项目 -
insert()
在迭代器指向的位置插入一个项目,迭代器会位于添加的项目之后 -
setValue()
对上一次跳过的项目进行赋值,也可以使用next(),previous()进行赋值,因为这二个函数返回列表中项目一个非const引用。
QMapIterator QMutableMapIerator
QMapIterator<QString,QString> i(map);//创建只读字典 i.findPrevious("xxx");向前查找键的值 QMutableMapIterator<QString,QString> j(map);// j.next().key().endsWith("city')
STL风格迭代器
只读迭代器QList<T> QList<T>::const_iterator 读/写迭代器QList<T>::iterator
QList<QString> list; QList<QString>::iterator i; //使用读/写迭代器 for(i = list.begin(); i != list.end(); ++i) { *i = (*i).toLower(); qDebug() << *i; } while(i != list.begin()){ --i; }
QList<QString>::const_iterator j; for(j = list.constBegin(); j != list.constEnd(); ++j) qDebug() << *j;
- *i 返回当前项目
- ++i 前移迭代器到下一个项目
- i+=n 使迭代器前移n个项目
- --i 使迭代器往回移动一个项目
- i -= n使迭代器回移n个项目
- i - j 返回迭代器i和迭代器j之间的项目的数目
foreach
QList<QString> list;
foreach(QString str, list){
qDebug() << str;
}
QMap<QString,int> map;
foreach(QString str,map.keys){
qDebug() << str << ":" << map.valus(str);
}
通用算法
在<QtAlgorithms>头文件中,Qt提供了一些全局的模板函数,这些函数可以使用在容器上的十分常用的算法。可以在任何提供了STL风格迭代器的容器类上使用这些算法,如果在目标平台上可以使用STL,那么可以使用STL算法来代替这些算法。
QStringList list;
QVector<QString> vect(3);
qCopy(list.begin(),list.end(),vect.begin());//qCopy算法,list中项目复制到vect中
bool ret1 = qEqual(list.begin(),list.end(),vect.begin());//qEqual算法,list的开始到结束的所有项目与vect的开始及其后面的等数量项目进行比较
QList<QString>::iterator i = qFind(list.begin(),list.begin(),"two");
qDebug() << *i;//从list中查找"two",返回第一个对应值得迭代器,如果没有找到返回end()
qFill(list.begin(),list.end(),"eleven");//将list中所有项目填充为eleven
int coutOf6 = 0;
qCount(list1.begin(),list1.end(),6,coutOf6);//查找6的个数
//返回第一个出现5的位置,如果没有返回5应该在的位置
//list1被查找的范围中项目必须是升序
QList<int>::iterator j = qLowerBound(list1.begin(),list1.end(),5);
list1.insert(j,5);
qStableSort(list2.begin(),list2.end());//比较稳定的排序算法,还有一种是qSort()
qDebug() << list2;
qSort(list2.begin(),list2.end(),qGreater<int>());//qGreater()可以在qSort()算法中使其反向排序
qSwap(pi,e);//交换pi和e的值
QString
编辑操作
QString str = "hello"; qDebug() << QObject::tr("字符串大小:") << str.size(); str[0] = QChar('H'); str.append(" Qt");//向字符串添加Qt str.replace(1,4,"i");//将第1个字符串开始的后面4个字符串替换为字符串“i” str.insert(2," my");//在第二个字符串后插入" my" str += str + "!!!"; str = " hi\r\n Qt! \n "; QString str1 = str.trimmed(); //去除字符串二端空白字符 QString str2 = str.simplified();//去除字符串俩端和中间多余空白字符 QStringList list = str.split(",",QString::SkipEmptyParts);//将字符串中有“,”的地方将其分割为多个子字符串,SkipEmptyParts表示跳过空项目 str = list.join(" ");//将各个子字符串合为一个字符串,中间用“ ”隔开 QString("").isEmpty();
查询操作
str.right(5);//包含右侧5个字符的子字符串 str.left(5);//包含左侧5个字符的子字符串 str.mid(2,3)//包含第二个字符以后3个字符的子字符串 str.indexOf("fei");//fei的位置 str.count('i');//str中i的个数 str.startsWith("ya");//str是否以ya开始 str.endsWith("lll")//str是否以lll结尾 str.contains("lin")//str是否包含lin
转换操作
str = "100"; str.toInt();//结果为100 int num = 45; QString::number(num);//结果为“45” QString::number(num,16);//结果为45的16进制显示 str = "FF"; bool ok; int hex = str.toInt(&ok,16);//结果为ok: true 255 num = 26; QString::number(num,16); str = "123.456"; str.toFloat();//结果为123.456 str = "abc"; str.toUpper();//结果为ABC str = "ABC"; str.toLower();//结果为abc int age = 22; QString name = "sss"; str = QStrign("name is %1,age iss %2").arg(name).arg(age);// str = "%1 %2"; qDebug() << str.arg(" %1f","hello");//结果为%1f hell0 qDebug() << str.arg(" %1f").arg("hello");//结果为hellof %2 str = QString("ni%1").arg("hi",5,'*');//结果为ni***hi,如果是-5nihi*** qreal value = 123.456; str = QString("number:%1").arg(value,0,'f',2);//结果为123,45 qPrintable(str);不会显示引号
QByteArray和QVariant
QByteArray提供了一个字节数组,可以用来存储原始字节(包括‘\0’),和传统的以‘\0’结尾的8位字符串