您的位置 首页 测评

我的QT5学习之路(三)――模板库、东西类和控件(上)

一、前言ldquo;合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下rdquo;,上一章我们知道了如何使用Qt创建简单的示例程序,了解了最基

一、前语  “合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下”,上一章咱们知道了怎么运用Qt创立简略的示例程序,了解了最根本的Qt结构,在进一步学习Qt结构和音讯机制前,咱们应该对Qt自身有一个更详尽的了解,这个了解便是Qt的模板库、东西类和控件。

回到顶部(go to top)

二、Qt的模板库、东西类和控件2.1 字符串类1、字符串的操作  咱们了解字符串的操作便是要了解字符串主要有哪些操作符,Qt根据C++承继和强化了string的功用,结构类型为QString,QString供给了一个二元的“+”和“+=”操作符,其间“+=”操作符功用和append函数办法具有相同的功用,是现在一个字符串结束追加另一个字符串,学习时可根据C++中String类进行比较。

1 QString str1=nihao;

2 QString str2=Qt;

3

4 str1+=str2; //str1=nihaoQt

5 str1=str1+str2; //str1=nihaoQtQt

6 str1.append(str2); //str1=nihaoQtQtQt

7 str1.append(yes); //str1=nihaoQtQtQtyes

Qt组合字符串的另一个函数 QString::sprintf(),此函数支撑的格局界说符和C++库中的函数sprintf界说的相同。Qt还供给了别的一种便利的字符串组合办法,运用QString::arg()函数,此函数的重载能够处理多种数据类型,一些重载具有额定的参数对字段的宽度、数字基数或许浮点数精度进行操控。相关于sprintf来说,srg是一个比较好的处理方案,因为它类型安全,彻底支撑Unicode,而且答应改动%n参数的次序。

1 QString str;

2 str=QString(%1 was born in %2 .).arg(Rimond).arg(1990);

3 //str=Rimond was born in 1990.

此外,QString也供给了一些其他组合字符串的办法

函数称号函数功用

insert()在原字符串特定的方位刺进另一个字符串

prepend()在原字符串的最初刺进另一个字符串

replace()用指定的字符串替代原字符串中的某些字符

为了处理特定场景比方去除一个字符串两头的空白(空白字符包含回车字符“\n”,换行字符“\r”,制表符“\t”和空格字符等),QString供给了特定的函数。

函数称号函数功用

trimmed() 移出字符串两头的空白字符

simplified()移除字符串两头的空白字符,运用单个空格字符“ ”替代字符串中呈现的空白字符

1 QString str= Hello \t QT \n ! ;

2 str=str.trimmed();

3

4 //str= Hello \t to \n you!

5 //假如运用str=str.simplified(),str的成果是“Hello Qt !”

2、查询字符串数据  查询字符串数据有多种款式。

(1) QString::startsWith()判别一个字符串是否以某个字符串最初。此函数具有两个参数,第一个参数指定了一个字符串,第二个参数指定是否巨细写灵敏(默许巨细写灵敏)。

1 QString str=Hello Qt!;

2 str.startsWith(Hello,Qt::CaseSensitive); //回来真

3 str.startsWith(Qt,Qt::caseSenstive); //回来假

(2) QString::endwith()相似于QString::startswith(),它用来判别一个字符串是否以某个字符串结束。

(3) QString::contains()判别一个指定的字符串是否呈现过。

1 QString str =Hello QT!;

2 str.contains(QT,Qt::CaseSensitive); //回来真

(4) QString类还重载了多种用于比较的操作符,用法可参照C++ string类中重载的比较操作符。此外,QString类增加了两个特别函数。

localeAwareCompare(const QString,const QString):静态函数,比较前后两个字符串,假如前面字符串小于后边字符串,则回来值为负整数;假如等于则回来0;假如大于则回来值为正整数,该函数用于比较根据本地字符集,而且肫教ㄏ喙氐模一般该函数用于向用户显现一个有序的字符串列表。

compare(const QString,const QString::CaseSensitivity):该函数能够指定是否进行巨细写的比较,而巨细写的比较胪耆根据字符的Unicode编码值的,而且是十分快的,回来值相似于localeAwareCompare函数。

3、字符串的转化  因为Qt的跨渠道型,可移植性等特色反映了其在字符串上的灵活性,QString类供给了丰厚的转化函数,能够完结讲一个字符串转化为数值类型或许其他的字符编码集。

(1) QString::toInt()函数完结了将字符串转化为整型数值,相似的函数还有toDouble()、toFloat()、toLong()、toLongLong()等。

1 QString str=125;

2 bool ok;

3 int hex=str.toInt(ok,16); //ok=true,hex=293

4 int dec=str.toInt(ok,10); //ok=true,dec=125

能够看到上面的16和10别离代表了进制,ok用于传递一个地址,表明转化成果。

(2) QString供给的字符串编码集的转化函数将会回来一个const char*类型版别的QByteArry,即结构函数QByteArry(const char*)结构的QByteArry目标。QByteArry类具有一个字符数组,它既能够存储原始字节(raw bytes),也能够存储传统的以“\0”结束的8位的字符串。在Qt中,运用QByteArry比运用const char*更为便利,且QByteArry也支撑隐式同享,转化函数有以下几种。

函数称号函数功用

toAscii() 回来一个ASCII编码的8位字符串

toLatin1()回来一个Latin-1编码的8位字符串

toUtf8()回来一个utf-8编码的8位字符串(utf-8是ASCII码的超集,它支撑整个Unicode字符集)

toLocal8Bit()回来一个体系本地编码的8位字符串

1 #include

2 #include

3 #include

4 #include

5

6 int main(int argc, char *argv[])

7 {

8 QCoreApplication a(argc, argv);

9 QString str=Hello Qt!;

10 QByteArray ba=str.toLatin1();

11 qDebug() ba;

12 ba.append(Hello,world!);

13 qDebug() ba.data();

14 return a.exec();

15 }

运转成果如下

提示:Qt5中去除了toAscii()函数,改用toLatin1()函数就可了,再便是debug环境下别忘了增加qDebug的头文件。

qDebug相似于cout格局输出。

附加:NULL字符串和空(empty)字符串的差异

一个NULL字符串便是运用QString的默许结构函数或许运用(const char*)0作为参数的结构函数创立的QString字符串目标;而一个空字符串是一个巨细为0的字符串。一个NULL字符串一定是一个空字符串,而一个空字符串未必是一个NULL字符串。

验证办法

1 QString().isNull(); //true

2 QString().isEmpty(); //true

3 QString().isNull(); //false

4 QString().isEmpty(); //true

2.2 容器类  同C++的规范模板库中的容器类作比较,Qt供给了一组通用的根据模板的容器类。这些容器更轻量、更安全而且更简单运用,一同还在速度、内存耗费和内联等方面进行了优化。

关于Qt容器中的存储数据类型也有要求,这些数据有必要是能够赋值的数据类型,换句话说便是该数据类型有必要有一个默许的结构函数(无参数结构函数)、一个仿制结构函数(仿制结构)和一个赋值操作符函数。

其实这样的数据类型包含了一般咱们运用的大多数数据类型,比方根本的数据类型(int和double等)和Qt的一些数据类型(如QString、QDate、QTime等)。可是,Qt的QObject及其他的子类(如QWidget和Qdialog等)是不能够存储在容器中的。

1 QList list; //error

2 QList

上述代码中,第一种是过错的。因为这些类(QObject及其他的子类)没有仿制结构函数和赋值结构函数。处理的办法便是运用指向这些类的指针来作为存储类型。

别的的一点便是Qt的容器类是能够嵌套的,这一点C++的STL也是能够做到的。

1 QHase

Qt的容器类为遍历其间的内容供给了以下两种办法:

(1)Java风格的迭代器

(2)STL风格的迭代器,能够同Qt和STL的通用算法一同运用,而且在功率上也技高一筹。

下面咱们将经过详细的容器类来详细的了解Qt容器类的功用和运用办法。

2.2.1 QList类、QLinkedList类和QVector类  首要咱们来看一下这三种容器类的操作时刻复杂度。

容器类查找(拜访)刺进头部增加尾部增加

QListO(1)O(n)Amort.O(1)Amort.O(1)

QLinkedListO(n)O(1)O(1)O(1)

QVectorO(1)O(n)O(n)Amort.O(1)

注:其间Amort.O(1)表明,假如仅完结一次操作,或许会有O(n)行为;可是假如完结屡次操作(比方n次),均匀成果将会是O(1)。

1、QList类

QList是咱们会常常运用的容器类,它存储给定数据类型T的一列数值。承继自QList类的子类有QItemSelection、QQueue、QSignalSpy及QStringList和QTestEvenList。QList不只供给了能够在列表进行追加的QList::append()和QList::prepend()函数,还供给了在列表中心完结刺进操作的函数QList::insert()。相关于任何其他的Qt容器类,为了使可执行代码尽或许的少,QList被高度优化。

QList保护了一个指针数组,该数组存储的指针指向QList存储的列表项的内容。因而,QList供给了根据下标的快速拜访。关于不同的数据类型,QList选用不同的存储战略,主要有以下几种。

(1)假如T是一个指针类型或许指针巨细的根本类型(便是说该根本类型占有的字节数和指针类型占有的字节数相同),QList会将数值直接存储在它的数组中。

(2)假如QList存储目标的指针,则该指针指向实践存储的目标。

1 #include

2 #include

3 #include

4

5 int main(int argc, char *argv[])

6 {

7 QCoreApplication a(argc, argv);

8 QList list;

9 //{}用来表明效果域

10 {

11 QString str(this is a test string);

12 list

13 }

14 qDebug()

15 return a.exec();

16 }

其间list

(2)QLinkedList类

QLinkedList是一个链式列表,它以非接连的内存块保存数据。QLinkedList不能运用下标,只能运用迭代器拜访他的数据项。与QList比较,当对一个很大的列表进行刺进操作时,QLinkedList具有更高的功率。

(3)QVector类

QVector在相邻的内存中存储给定数据类型T的一组数值。在一个QVector的前部或许中心方位进行刺进操作的速度是很慢的,这是因为这样的操作将导致内存中很多的数据被移动,这事有QVector存储数据的办法决议的。

QVector既能够运用下标拜访数据项,也能够运用迭代器拜访数据项。承继自QVector类的子类有QPolygon、QPolygonF、QStack。

注:其实往常咱们用QList就能够,它既能够是存储指向存储类型的指针,也能够对小的数据进行直接存储。

附:STL风格迭代器遍历容器

关于每一个容器类,Qt都供给了两种类型的STL风格迭代器数据类型:一种供给只读拜访;另一种供给读写拜访。因为只读类型的迭代器的运转速度要比读写迭代器的运转速度快,主张尽或许运用只读类型的迭代器。

容器类只读迭代器类读写迭代器类

QList,QQueueQList::const_itertorQList::itertor

QLinkedListQLinkedList::const_itertorQLinkedList::itertor

QVector,QStackQVector::const_itertorQVector::itertor

1 #include

2 #include

3 #include

4

5 int main(int argc, char *argv[])

6 {

7 QCoreApplication a(argc, argv);

8 QList list;

9 for(int j=0;j10;j++)

10 list.insert(list.end(),j);

11 QList::iterator i;

12 for(i=list.begin();i!=list.end();i++)

13 {

14 printf(%d ,*i);

15 *i=(*i)*10;

16 }

17 QList::const_iterator ci;

18 for(ci=list.constBegin();ci!=list.constEnd();ci++)

19 printf(%d ,*ci);

20 return a.exec();

21 }

注:假如运用qDebug输出的话,我以为每次迭代都会生成一个qDebug的暂时目标,而且主动增加换行,所以我改成了printf(偷闲),别的关于容器类运用办法能够参阅C++ STL的运用办法。

2.2.2 QMap类和QHash类  QMap类和QHash类具有十分相似的功用,他们的不同仅在于:

1、QHash具有比QMap更快的查找速度

2、QHash以恣意次序存储数据项,而QMap总是依照Key次序存储数据;

3、QHash的键类型Key有必要供给operator==()和一个大局的qHash(Key)函数,而QMap的键类型Key有必要供给operator()函数。

QMap和QHash的时刻复杂度比较

1、QMap类

QMap

2、QHash类

QHash

附:STL风格迭代器遍历容器

和上面提到的容器相同,Qt也供给了两种类型的STL风格迭代器数据类型。

容器类只读迭代器读写迭代器

QMap

QHase

1 #include

2 #include

3 #include

4 int main(int argc, char *argv[])

5 {

6 QCoreApplication a(argc, argv);

7 QMap

8 map.insert(lili,1990);

9 map.insert(wangli,1992);

10 map.insert(zhangli,1989);

11 QMap

12 for(i=map.constBegin();i!=map.constEnd();i++)

13 qDebug()

14 QMap

15 mi=map.find(lili);

16 if(mi!=map.end())

17 mi.value()=1995;

18 QMap

19 for(modi=map.constBegin();modi!=map.constEnd();modi++)

20 qDebug()

21 return a.exec();

22 }

好了,关于字符串类和容器类先说这么多,如有过错,欢迎纠正。

no pains ,no gains. 给自己加油,为未来斗争。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ceping/150012.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部