1.Windows Qt环境安装步骤详解
1.下载路径
https://download.qt.io/archive/qt/5.9/5.9.9/
2.安装
2.QT Creator工具的介绍与使用
1.QT页面讲解
2.QT工具介绍
Qt Assistant(Qt助手)
Qt Desiginer(Qt设计师)
Qt Example And Dmeos(QT演示程序与案例)
Qt Linguist (Qt语言)
3.剖析QT程序
【运行结果】
MainWindow w;
w.resize(500,300);//设置运行窗口尺寸大小
w.setWindowTitle("不想学辣");
w.show();
label = new QLabel("能不能让我早点找到工作!",this);
label->setGeometry(50,50,330,100);
label->setStyleSheet("QLabel{background-color:green;color:red}");
label->setFont(QFont("隶书",22));
3.Qt信号与槽机制
1.Qt信号与槽机制原理(Signal &Slot)
1.信号(signal):所谓信号槽(观察者模式),信号本质是事件。信号展现方式就是函数,当某一个事件发生之后,则发出一个信号(signal)。
2.槽(slot):就是对信号相应的函数,槽就是一个函数。槽函数与普通函数区别:
槽函数可以与一个信号关联,当信号被发射的时候,关联的槽函数被自动执行处理。信号与槽关联是使用QObject::connect()函数进行实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cCbYY9um-1683942778855)(E:\QT\QT从入门到精通专栏【开发基础体系】\图片\11.png)]
信号函数只需要声明(不需要定义(实现)),而槽函数需要定义(实现)。
信号和槽机制底层是通过函数之间相互调用实现的。每个信号都可以用函数来表示,称为信号函数;每个槽也可以用函数表示,成为槽函数。
槽函数可以使用public slots/protected slots/private slots 修饰。signals和slots是Qt开发当中在C++语言基础之上扩展的关键词,专门用于指明信号函数和槽函数。
2.QObject::connect(…);
[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
参数1 Sender:发出信号的对象
参数2 signal:sender对象的信号
参数3 receiver:信号接收这。
参数4 method:receiver对象的槽函数,当检测到sender信号,receiver对象调用method方法。
3.信号与槽机制连接方式
一个信号可以跟另一个信号相连:
connect(object1,SIGNAL(signal1),object2,SIGNAL(signal2));
同一个信号可以跟多个槽相连:
connect(object1,SIGNAL(signal2),object2,SIGNAL(slot2));
connect(object1,SIGNAL(signal2),object2,SIGNAL(slot1));
同一个槽可以响应多个信号:
connect(object1,SIGNAL(signal2),object2,SIGNAL(slot2));
connect(object3,SIGNAL(signal2),object2,SIGNAL(slot1));
常用链接方案采用
connect(object1,SIGNAL(signal),object2,SLOT(slot2));
4.信号与槽优缺点
优势:松散耦合,类型安全
一个类要支持信号和槽就必须从QObject或QObject的子类继承。
缺点:不支持对模板的使用
5.信号与槽效率
通过增强对象的之间通信的灵活性,但是也会损失一些性能。
通过传递一个信号来调用槽函数将会比直接调用非虚函数运行速度慢,主要原因:
多线程的时候,信号可能需要排队等待
编组/解组传递的参数
安全地遍历所有的关联
需要定位接收信号的对象。
信号与槽实战应用
源码
#include "dialog.h"
#include<QGridLayout>
const static double PI = 3.14159;
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
//创建第一个标签(提示用户输入圆球的半径)
label1 = new QLabel(this);
label1->setText(tr("请输入圆球的半径:"));
//创建第二个标签(专门用来显示计算圆球体积的结果)
label2 = new QLabel(this);
//创建一个编辑框控件(专门用于接受用户的输入圆球半径的值)
lEdit = new QLineEdit(this);
//创建命令按钮
pbt = new QPushButton(this);
pbt ->setText(tr("计算圆球体积"));
//表格布局
QGridLayout *mLay = new QGridLayout(this);
mLay->addWidget(label1,0,0);
mLay->addWidget(lEdit,0,1);
mLay->addWidget(label2,1,0);
mLay->addWidget(pbt,1,1);
connect(pbt,SIGNAL(clicked()),this,SLOT(CalcBallVolume()));
}
void Dialog::CalcBallVolume()
{
//槽函数计算圆球体积
bool isLoop;
QString tempStr;
QString valueStr(lEdit->text());
int valueInt = valueStr.toInt(&isLoop);
double dVSum = 4.0/3.0*PI*valueInt*valueInt*valueInt;
label2->setText(tempStr.setNum(dVSum));
}
4.Qt字符串类应用与常见数据类型
1.Qt字符串类应用
1.操作字符串
//1.QString 提供二元 "+"操作符应用,功能一样 "+="
QString str1 = "Ling";
str1=str1+"Sheng EDU";
qDebug()<<str1;//打印信息
qDebug()<<qPrintable(str1);//去掉双引号
QString str2="12345";
str2+="ABCDE";
qDebug()<<qPrintable(str2);
//2.QString::append()函数
QString str1 = "Good";
QString str2 = "bye";
str1.append(str2);//str1="Good Bye"
qDebug()<<qPrintable(str1);
str1.append("Hello World");//str1="Good Bye"
qDebug()<<qPrintable(str1);
// 3.组合字符串:QString::sprintf()函数
QString strtemp;
strtemp.sprintf("%s","Hello");
qDebug()<<qPrintable(strtemp);
strtemp.sprintf("%s","Hello World");
qDebug()<<qPrintable(strtemp);
strtemp.sprintf("%s %s","Welcome","to you");
qDebug()<<qPrintable(strtemp);
// 4.字符串组合方式QString::arg()函数
QString strTemp;
strTemp = QString("%1 was born in %2.").arg("sunny").arg(2000);
qDebug()<<strTemp;
2.查询字符串
//4.QString::strstsWith()函数:查找开头 对应关系函数QSting::ends();
//第一个参数代表查找字符串的头串,第二个参数代表区分不大小写查找
QString strTemp="How are you";
qDebug()<<strTemp.startsWith("How",Qt::CaseSensitive);//true
qDebug()<<strTemp.startsWith("are",Qt::CaseInsensitive);//false
//5.QStirng::contains()函数 查找子串
QString strTemp="How are you";
qDebug()<<strTemp.startsWith("How",Qt::CaseSensitive);//true
//6.QSting::toInd() 类似函数toDouble(),toFloat()...
QString str = "25";
bool isloop;
int hex = str.toInt(&isloop,16); //isloop=true hex=37
qDebug()<<"isloop="<<isloop<<","<<"hex="<<hex<<endl;
//7.QString::compare()
int a1 = QString::compare("abcd","ABCD",Qt::CaseInsensitive);
int b1 = QString::compare("about","Cat",Qt::CaseSensitive);
int c1 = QString::compare("abcd","Cat",Qt::CaseInsensitive);
cout<<"a1="<<a1<<","<<"b1="<<b1<<","<<"c1="<<c1;
//8.Qt将 QString转换成ASCII码
QString str = "ABC abc";
QByteArray bytes=str.toUtf8();
for(int i = 0 ;i<str.size();i++)
qDebug()<<int(bytes.at(i));
2、Qt常见基本数据类型(注意:定义在#include)
测试用例
//9.QDateTime QByteArray
QDateTime dt;
QString strDT = dt.currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
qDebug()<<strDT<<endl;
QByteArray a1("Qt Creator Hello World.");
QByteArray b1=a1.toLower();//将字符串大写字母转换小写
QByteArray b2=a1.toUpper();//将字符串大写字母转换小写
qDebug()<<b1<<endl;
qDebug()<<b2<<endl;
5.QMap类 &QHash类 &QVector类
1.QMap类
QMap<Key,T>提供一个类型为Key的键到类型为T的值的映射,通常QMap存储的数据形式是一个键对应一个值,并且按照键Key的次序存储数据,为了能够支持一键多值的情况,QMap提供QMap<Key,T>::insertMulti()和QMap<Key,T>::valuse()函数。QMultiMap类来实例化一个QMap对象。
// //QMap类 自带排序
// //1.创建QMap实例,第一个参数为QString类型的键,第二个参数为int类型的值
// QMap<QString,int> qmap;
// //插入数据信息,他有两种方式进行操作
// qmap["Chinese"] =119;
// qmap["English"] =120;
// qmap.insert("Math",115);
// qmap.insert("Physics",99);
// qmap.insert("Chemistry",100);
// qDebug()<<qmap<<endl;
// //删除数据信息key键
// qmap.remove("Chemistry");
// qDebug()<<qmap<<endl;
// //遍历QMap类的实例数据信息
// //1.迭代器
// QMapIterator<QString,int> itr(qmap);
// while(itr.hasNext())
// {
// itr.next();
// qDebug()<<itr.key()<<":"<<itr.value()<<" ";
// }
// //2.STL类型迭代
// qDebug()<<endl;
// QMap<QString,int>::const_iterator stritr = qmap.constBegin();
// while(stritr!=qmap.constEnd())
// {
// qDebug()<<stritr.key()<<":"<<itr.value()<<" ";
// stritr++;
// }
// //通过key键/T键-->来查找
// qDebug()<<"根据key键查找对应的T键值"<<qmap.value("Math")<<endl;
// qDebug()<<"通过T值来找对应的Key键"<<qmap.key(99)<<endl;
// //修改键值
// //一个键对应一个值,再次调用insert()函数将覆盖之前的值
// qmap.insert("Math",118);
// qDebug()<<qmap.value("Math");
// //查询是否包含某个键
// qDebug()<<"result="<<qmap.contains("Chinese");
// qDebug()<<"result="<<qmap.contains("Chemistry");
// //输出所有QMap实例化:Key键和T键值
// qDebug()<<endl;
// QList<QString> aKeys = qmap.keys();
// qDebug()<<aKeys;
// QList<int> aValues = qmap.values();
// qDebug()<<aValues;
// //一个键对应多个值
// //直接使用QMultiMap类来实例化一个QMap对象
// qDebug()<<endl;
// QMultiMap<QString,QString> mulmap;
// mulmap.insert("student","no");
// mulmap.insert("student","name");
// mulmap.insert("student","sex");
// mulmap.insert("student","age");
// mulmap.insert("student","high");
// mulmap.insert("student","weight");
// qDebug()<<mulmap;//从输出结果看出 mulmap 仍然是一个QMap对象
2.QHash类
QHash<Key,T>具有与QMap几乎完全相同的API,QHash维护着一张哈希表(Hash Table),哈希表的大小与QHash的数据项的数目相适应。
QHash以任意的顺序组织它的数据。当存储数据的顺序无关紧要时,建议使用QHash作为存放数据的容器。
// //QHash类
// QHash<QString,int> qhash;
// qhash["key 1"] = 3;
// qhash["key 1"] = 8;
// qhash["key 4"] = 4;
// qhash["key 2"] = 2;
// qhash.insert("key 3",30);
// QList<QString> list = qhash.keys();
// for(int i = 0;i<list.length();i++)
// qDebug()<<list[i]<<","<<qhash.value(list[i]);
// //QHash内部的迭代器QHahsIterator类
// QHash<QString,int> hash;
// hash["key 1"] = 33;
// hash["key 1"] = 44;
// hash["key 4"] = 55;
// hash["key 2"] = 66;
// hash.insert("key 3",100);
// QHash<QString,int>::const_iterator iterator;
// for(iterator =hash.begin();iterator!=hash.end();iterator++)
// qDebug()<<iterator.key()<<"--->"<<iterator.value();
QMap与QHash区别
1.QHash与QMap的功能差不多,但QHash的查找速度更快
2.QMap是按照键的顺序存储数据,而QHash是任意顺序存储的
3.QMap的键必须提供“<“运算符,而QHash的键必须提供”=="运算符和一个名为qHash()的全局散列函数
3.QVerctor类
QVector在相邻的内存当中存储给定数据类型T的一组数值。在一个QVector的前部或者中间位置进行插入操作的速度是很慢的,这是因为这样将导致内存中的大量数据被移动,这是由QVector存储数据的方式决定的
//QVector类
//QVector<T>是Qt的一个容器类
QVector<int> qvarray;
//第一种方式进行赋值
qvarray<<30;
qvarray<<30;
qvarray<<10;
qvarray<<20;
//第二种方式赋值
qvarray.append(50);
qvarray.append(60);
qvarray.append(80);
qvarray.append(70);
qDebug()<<qvarray<<endl;
//求出QVector类容器的实例化:元素个数
qDebug()<<"qvarray count="<<qvarray.count()<<endl;
//遍历所有元素
for(int i =0;i<qvarray.count();i++)
qDebug()<<qvarray[i];
//删除qvr容器里的元素
qDebug()<<endl;
qvarray.remove(0);
for(int i =0;i<qvarray.count();i++)
qDebug()<<qvarray[i];
qDebug()<<endl;
qvarray.remove(2,3);//从第2个元素开始,删除后面3个元素
for(int i =0;i<qvarray.count();i++)
qDebug()<<qvarray[i];
//判断容器是否包含某个元素
qDebug()<<endl;
qDebug()<<"result:"<<qvarray.contains(90)<<endl;
qDebug()<<"result:"<<qvarray.contains(70)<<endl;
6.QList&QLinkedList类
1.QList类
对于不同的数据类型,QList采取不同的存储策略,存储策略如下:
1.如果T是一个指针类型或指针大小的基本类型(该基本类型占有的字节数和指针类型占有的字节数相同),QList将数值直接存储在它的数组当中。
2.如果QList存储对象的指针,则该指针指向实际存储的对象。
// //QList类
// QList<int> qlist;//初始化一个空的QList<int>列表
// for(int i=0;i<10;i++)
// qlist.insert(qlist.end(),i+10);
// qDebug()<<qlist;
// //通过QList<int>::iterator读写迭代器
// QList<int>::iterator x;
// qDebug()<<"Result";
// for(x= qlist.begin();x!=qlist.end();x++)
// {
// qDebug()<<(*x);
// *x = (*x) *10+6;
// }
// //初始化一个QList<int>const_iterator只读迭代器
// qDebug()<<endl;
// qDebug()<<"Result";
// QList<int>::const_iterator qciter;
// //输出列表所有的值
// for(qciter=qlist.constBegin();qciter!=qlist.constEnd();qciter++)
// qDebug()<<*qciter;
// //向qlist添加元素
// qlist.append(666);
// QList<int>::iterator itr1;
// qDebug()<<"Result";
// for(itr1= qlist.begin();itr1!=qlist.end();itr1++)
// qDebug()<<(*itr1);
// //查询qlist当中元素
// qDebug()<<endl;
// qDebug()<<"Result3";
// qDebug()<<qlist.at(3);
// qDebug()<<qlist.contains(77);
// qDebug()<<qlist.contains(166);
// //修改qlist列表里面的元素值
// qDebug()<<endl;
// qDebug()<<"Result4:";
// qlist.replace(5,888);
// qDebug()<<qlist;
// //删除元素
// qDebug()<<endl;
// qDebug()<<"Result5:";
// qlist.removeAt(0);
// qlist.removeFirst();
// qlist.removeAt(6);
// qDebug()<<endl;
// QList<int>::iterator itr2;
// for(itr2= qlist.begin();itr2!=qlist.end();itr2++)
// qDebug()<<(*itr2);
2.QLinkedList类
QLinkedList是一个链式列表,它以非连续的内存块保存数据。QLinkedList不能使用下标,只能使用迭代器访问它的数据项。与QList相比,当对一个很大的列表进行插入操作时,QLinkList具有更高的效率
//QLinkedList类
QLinkedList<QString> qAllMonth;
qDebug()<<"Result";
for(int i =1;i<=12;i++)
qAllMonth<<QString("%1%2").arg("Month:").arg(i);
//读写迭代器
qDebug()<<"Result1";
QLinkedList<QString>::iterator itrw = qAllMonth.begin();
for(;itrw!=qAllMonth.end();itrw++)
qDebug()<<*itrw;
//只读迭代器
qDebug()<<"Result2";
QLinkedList<QString>::const_iterator itr = qAllMonth.constBegin();
for(;itr!=qAllMonth.constEnd();itr++)
qDebug()<<*itr;
7.QVariant类应用
QVariant类本质为C++联合(Union)数据类型,它可以保存很多Qt类型的值,包括QBrush,QColor,QString等等,也能够存放Qt的容器类型的值。
QVariant::StringList是Qt定义的一个QVariant::type枚举类型的变量,其他常用的枚举类型变量如下表所示
//创建结构体学生
struct student
{
QString name;
int numb;
int score;
};
Q_DECLARE_METATYPE(student);
QVariant qv1(298);
qDebug()<<"qv1:"<<qv1.toInt();
QVariant qv2("LingShengEDU");
qDebug()<<"qv2:"<<qv2.toString();
QMap<QString,QVariant> qmap;
qDebug()<<endl;
qmap["int"]=20000;//整型
qmap["double"]=99.88;//浮点型
qmap["string"]="Good";//字符串
qmap["color"]=QColor(255,255,0);//QColor类型
//输出:转换函数来处理
qDebug()<<qmap["int"]<<qmap["int"].toInt();
qDebug()<<qmap["double"]<<qmap["double"].toDouble();
qDebug()<<qmap["string"]<<qmap["string"].toString();
qDebug()<<qmap["color"]<<qmap["color"].value<QColor>();
//创建一个字符串列表:QStringList
qDebug()<<endl;
QStringList qsl;
qsl<<"A"<<"B"<<"C"<<"D"<<"E"<<"F";
QVariant qvsl(qsl);//将列表存储在一个QVariant变量
if(qvsl.type()==QVariant::StringList)
{
QStringList qlist=qvsl.toStringList();
for(int i = 0;i<qlist.size();i++)
qDebug()<<qlist.at(i);//输出列表信息
}
//结构体类型和QVariant类配合使用
qDebug()<<endl;
student stu;
stu.numb=202201;
stu.name= "sunny";
stu.score = 715;
//使用静态方法保存数据
QVariant qstu = QVariant::fromValue(stu);
if(qstu.canConvert<student>())
{
student temp = qstu.value<student>();
student qtemp = qvariant_cast<student>(qstu);
qDebug()<<"Student:numb"<<temp.numb<<"Student:name:"
<<temp.name<<"Student:score:"<<temp.score<<endl;
qDebug()<<"Student:numb"<<qtemp.numb<<"Student:name:"
<<qtemp.name<<"Student:score:"<<qtemp.score<<endl;
8.常用算法以及正则表达式
1.Qt5常用算法:
1.double c =qAbs(a):函数qAbs() 返回double型数值a的绝对值;
2.double max = qMax(b,c):函数qMax() 返回两个数值中的最大值;
3.int bn = qRound(b) :返回一个与浮点数最接近的整数值(四舍五入);
4.int cn =qSwap(bn,cn):交换两数的值;
//求绝对值
double result = qAbs(x);
qDebug()<<"x="<<result;
//求最大值
double maxresult = qMax(x,y);
qDebug()<<"maxresult="<<maxresult;
//四舍五入求整数值
int result2 = qRound(y);
qDebug()<<"result2="<<result2;
//四舍五入求整数值
int result3 = qRound(x);
qDebug()<<"result2="<<result3;
//两数交换
qSwap(x,y);
qDebug()<<x<<","<<y<<endl;
2.正则表达式
正则表达式,又称规则表达式(Regular Expression,在代码中常简写为regex,regexp或RE),是一种文本模式,包括普通字符(例如,a到z之间的字母)和特殊字符(称为元字符)。正则表达式使用单个字符串来描述,匹配一系列某个语法规则的字符串,通常被用来检索,替换那些符合某个模式(规则)的文本。正则表达式描述一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串,将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
正则表达式由表达式(expressions)、量词(quantifiers)、断言(assertions)组成。
(1)最简单的表达式是一个字符,字符集可以使用表达式如"[AEIOU]“,表示匹配所有的大写元音字母;使用”[ ^ AEIOU]" ,表示匹配所有非元音字母,即辅音字母;连续的字符集可以使用表达式如"[a-z]",表示匹配所有的小写英文字母
(2)量词说明表达式出现的次数,如"x[1,2]"表示"x"可以至少有一个,至多有两个。
正则表达式的量词
正则表达式的断言
案例-做一个手机号码匹配
/*
*通过正则表达式匹配:手机号码
* 根据目前国家对手机号码规定:11位数字,其中各段有不同的编码方式:
* 前三位:网络识别码(中国移动,中国联通,中国电信)
* 后面第8位到11位为用户号码
* 中国移动:134 159 158 188
* 中国联通:130 133 189 156
*
* 相当于1开头,第2位3 5 8,共计有11位。
*/
QString qMobileNumber="11922227896";
std::regex reg("^1(3|5|8)\\d{9}$");
std::string UserTelIdString=qMobileNumber.toStdString();
qDebug()<<"Phone Number:"<<qMobileNumber;
//进行匹配
bool bResult = std::regex_match(UserTelIdString,reg);
if(!bResult)
{
qDebug()<<"MibleNumber"<<"-->Error moble phone number.";
}
else
{
qDebug()<<qMobileNumber<<"-->Right mobile phone number.";
}