QT基础知识
文章目录
1.常用的快捷键
F1 查看帮助(光标选中的函数或者类的信息),一次半屏显示,按两次全屏显示
F2 跳转到光标函数定义或者源码(ctrl+鼠标左键效果是一样的)
F4 对应文件的头文件和源文件之间切换
Ctrl+B 编译工程
Ctrl+R 运行工程
Ctrl+I 自动对齐
Ctrl+/ 注释行,取消注释行
Ctrl+ Shift + < 折叠代码块
Ctrl+ Shift + > 展开代码块
Alt +0 关闭/打开左侧显示
Ctrl+Tab 快速切换已打开的文件
修改全局变量和函数名 光标按下Ctrl+Shift+R,修改后按Replace即可(变量名出现红色框表示激活全局修改功能,整个工程里面对应的变量名都会修改,修改完毕后,移开光标,再次按下Ctrl+Shift+R保存)
2.多线程编译
-j16是开启16线程
-j4一般电脑够用
新版本的QtCreator会根据电脑核心自动设置多线程编译
3.pro文件常用的模块
QT+=\
sql\ #数据库
network\ #tcp/udp网络
xml\ #xml文件
gui\ #图形用户界面
qml\ #使用QML语言创建用户界面所需的QML类型
widgets\#桌面程序widgets,对应于QML
4.调试输出
头文件:
#include
qDebug—调试信息提示
qWarning–一般的警告提示
qCritical—严重错误提示
qFatal—致命错误提示
例如:在main.cpp添加调试信息
5.Qstring字符串类型
添加的头文件是#include<QSting>
5.1Qstring支持的运算符
=赋值+=追加,将运算符左边和右边的字符串拼接后,赋值给左边对象<小于号<=小于等于=等于。左右两边的字典序一样时为真!=不等于,左右两边不一样时候为真>大于>=大于等于[]从指定位置取出QChar字符,另外还可以直接修改指定位置的QChar+友元函数,将两个字符串拼接返回成全新的字符串对象
5.3常用的构造类型
QString()QString(QChar ch)QString(int size,QChar ch)QString(constchar*str)QString(const QbyteArray &ba)
整型转QString原型示例
static QString number(int,int base=10)
QString &setNum(int n,int base=10)
QString str,str1;
str=QString::number(888);
str1.setNum(999);//str="888",str1="999"
5.4QString类型转基本数据类型
shorttoShort(bool *ok=0,int base=10)const;
ushort toUShort(bool *ok=0,int base=10)const;inttoInt(bool *ok=0,int base=10)const;
uint toUInt(bool *ok=0,int base=10)const;longtoLong(bool *ok=0,int base=10)const;
ulong toULong(bool *ok=0,int base=10)const;
qlonglong toLongLong(bool *ok=0,int base=10)const;
qulonglong toULongLong(bool *ok=0,int base=10)const;floattoFloat(bool *ok=0)const;doubletoDouble(bool *ok=0)const;
5.5QString转QByteArray类型
相关的函数接口
QByteArray toLatin1()const
QByteArray toLocal8Bit()const//支持中文编码
QByteArray QSting::toUtf8()const//转为UTF-8编码
5.6QString类转为char类型字符串
1.不包含中文的转换格式
QString str("123456789");char*ch;
QByteArray by=str.toLatin1();
ch=by.data();qDebug()<<ch;
2.包含中文的转换格式
QString str="123456中文转换输出";
std::string stdstr=str.toStdString();constchar* ch=stdstr.c_str();qDebug()<<ch;
5.7字符串拼接
QString重载了“+=”运算符,还可以使用append成员函数来完成拼接功能。
QString &QString::append(const QString &str)
QString &QString::append(QChar ch)
QString &QString::append(const QChar *str,int len)
QString &QString::append(const QStringRef &reference)
QString &QString::append(QLatin1String str)
QString &QString::append(constchar*str)
QString &QString::append(const QByteArray &ba)
实例:
//方式一
QString x="free";
QString y="dom";
x.append(y);qDebug()<<x;//方式二
QString x="free";
QString y="dom";
x+=y;qDebug()<<x;//x=freedom
5.8计算字符串的个数
int QString::count()constint QString::size()const
注意:中文和英文在这里只算一个,如果将中文计算为两个字符,需要转为QByteArray类再进行计算
实例:
//中英文只算一个字符
QString str("QT5 学习");qDebug()<<str.size();qDebug()<<str.count();//输出为6
//中文算两个字符
QString str("QT5 学习");
QByteArray byte=str.toLocal8Bit();qDebug()<<byte.size();//输出为8
5.9QString标记替换
类比于C语言中sprintf格式化打印函数
函数原形:arg是一个重载函数
QString::arg(const QString &a,int fieldWidth =0, QChar fillChar =QLatin1Char(' '))const
1)字符串实例:
QString text("abcd");
text+=QString("%1%2%3%4").arg("11","22","33","44");qDebug()<<text;//%是一个标识符,代替arg成员函数对应形参//输出:abcd11223344
注意:一个argv的参数字符串替换的%号最大个数为%9,超过9个需要再加一个.arg()即可
2)整数替换实例:
QString text("abcd");
text+=QString("%1%2%3%4").arg(11).arg(22).arg(33).arg(44);qDebug()<<text;//输出:abcd11223344
3)浮点数替换实例:
QString text("abcd"); text+=QString("%1%2%3%4").arg(11.22).arg(22.33).arg(33.44).arg(44.55);qDebug()<<text;//输出:abcd11.2222.3333.4444.55
4)字符替换实例:
QString text("abcd"); text+=QString("%1%2%3%4").arg(A).arg(B).arg(C).arg(D);qDebug()<<text;//输出:abcdABCD
5.10字符串的比较
字符串的比较也可以使用符号进行比较,QString重载了>,<,==,<=,>=符号
1)函数原形
[static]int QString::compare(const QString &s1,const QString &s2, Qt::CaseSensitivity cs = Qt::CaseSensitive)
2)大小写敏感设置
enumQt::CaseSensitivity
Qt::CaseInsensitive 0//不敏感
Qt::CaseSensitive 1//敏感
3)字符串的比较实例
int
x=QString::compare("aUtO","AuTo",Qt::CaseInsensitive);//x==0qDebug()<<x;int y=QString::compare("auto","Car",Qt::CaseSensitive);qDebug()<<y;//y>0int z=QString::compare("auto","Car",Qt::CaseInsensitive);qDebug()<<z;//z<0
5.11字符串的查找
解析字符串用的比较多,c语言中使用strstr函数进行字符串查找,对于字符串查找功能QString类提供了contains和count两个成员函数
1)函数原形
bool QString::contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitivity)constint QString::count(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive)const
2)大小写敏感设置
enumQt::CaseSensitivity
Qt::CaseInsensitive 0//不敏感
Qt::CaseSensitive 1//敏感
3)查找字符串是否存在
QString str="hello world";
bool x=str.contains("hello",Qt::CaseInsensitive);qDebug()<<x;//true
4)查找字符串出现的次数
QString str="123123123";qDebug()<<str.count("123");//3
5.12填充字符串
使某个字段填满字符串,也就是说字符串里所有只读都有等长度的ch来代替
1)函数原形
QString::fill(QChar ch,int size=-1)
2)实例
QString str="hello";
str.fill('z');qDebug()<<str;//zzzzz
str.fill('A',2);qDebug()<<str;//AA
5.13从字符串里查找相同的某个字符串str
1)函数原形
int QString::indexOf(QLatin1String str,int from =0, Qt::CaseSensitivity cs = Qt::CaseSensitive)const
2)实例
QString x="apple is red";
QString y="apple";qDebug()<< x.indexOf(y);//0qDebug()<<x.indexOf(y,1);//-1qDebug()<<x.indexOf(y,10);//-1qDebug()<<x.indexOf(y,11);//-1
5.14指定位置插入字符串
1)函数原形
QString &QString::insert(int position,const QString &str)
2)实例
QString str ="Meal";
str.insert(1,QString("ontr"));qDebug()<<str;//Montreal
5.15判断字符串是否为空
1)函数原形
bool QString::isEmpty()const
2)实例
QString().isEmpty();// returns trueQString("").isEmpty();// returns trueQString("x").isEmpty();// returns falseQString("abc").isEmpty();// returns false
5.16判断字符串是否存在
1)函数原形
bool QString::isNull()const
2)实例
QString().isNull();// returns trueQString("").isNull();// returns falseQString("abc").isNull();// returns false
5.17从左向有截取字符串
1)函数原形
QString QString::left(int n)const
2)实例
QString x ="Pineapple";
QString y = x.left(4);// y == "Pine"
5.18从中间截取字符串
1)函数原形
QString QString::mid(int position,int n =-1)const
2)实例
QString x ="Nine pineapples";
QString y = x.mid(5,4);// y == "pine"
QString z = x.mid(5);// z == "pineapples"
5.19删除字符串中间某个字符
1)函数原形
QString &QString::remove(int position,int n)2)实例
QString s ="Montreal";
s.remove(1,4);// s == "Meal"
5.20替换字符串中的某些字符
1)函数原形
QString &QString::replace(int position,int n,const QString &after)2)实例
QString x ="Say yes!";
QString y ="no";
x.replace(4,3, y);// x == "Say no!"
5.21以某个字符切割字符串
1)函数原形
QString QString::section(QChar sep,int start,int end =..., QString::SectionFlags flags = SectionDefault)const2)实例
QString str;
QString csv ="forename,middlename,surname,phone";
QString path ="/usr/local/bin/myapp";// First field is empty
QString::SectionFlag flag = QString::SectionSkipEmpty;
str = csv.section(',',2,2);// str == "surname"
str = path.section('/',3,4);// str == "bin/myapp"
str = path.section('/',3,3, flag);// str == "myapp"
5.22把整型,浮点型,或其他类型转化为QString
QString &QString::setNum(int n,int base =10)
6.容器类
QList是一种表示链表的模板类,Qt的一种泛型容器类,它以链表方式存储一组值,并能对这组数据进行快速索引,还提供了快速插入和删除等操作。
QList与QLinkedList和QVector提供的操作及其相似,大多数的操作使用QList就可以了,其API是基于索引(index)的,由于内存中的存储方式,比QVector更快,比QLinkedList更方便,QLinkedList的API是基于迭代器的。
6.1构建QList列表
使用QList类需要先添加==#include==头文件
1、构建QString 类型的列表,并输出其中的值
/*构建一个列表类*/
QList<QString>my_list;/*向列表中填充数据*/
my_list<<"123"<<"456"<<"789";/*打印出列表中的数据*/for(int i=0;i<my_list.count();i++){//取出列表中指定的值qDebug()<<my_list.at(i);}//“123” “456” “789”
2、构建int类型的QList列表,并输出其中的值
/*构建一个列表类*/
QList<qint32>my_list;/*向列表中填充数据*/
my_list<<123<<456<<789;/*打印出列表中的数据*/for(int i=0;i<my_list.count();i++){//取出列表中指定的值qDebug()<<my_list.at(i);}//123 456 789
6.2插入数据
void QList::append(const T &value)//该函数时用于在列表的结尾处插入数据
示例:
QList<QString>list;
list.append("one");
list.append("two");
list.append("three");for(int i=0;i<list.count();i++){//取出列表中指定的值qDebug()<<list.at(i);}//"one" "two" "three"
6.3搜索列表中数值出现的位置
LastIndexOf是从字符串末尾开始检索的,检索到子字符,则返回子字符在字符串中的位置,(位置从前往后数,最小位是0,也就是从第0位开始算起)未检测到则返回-1。
int QList::lastIndexOf(const T &value,int from =-1)const
示例:
QList<QString>list;
list <<"A"<<"B"<<"C"<<"B"<<"A";qDebug()<< list.lastIndexOf("B");// returns 3qDebug()<< list.lastIndexOf("B",1);//returns 1 //从第一个位置开始往前查找qDebug()<< list.lastIndexOf("B",2);// returns 1qDebug()<< list.lastIndexOf("B",3);// returns 3qDebug()<< list.lastIndexOf("B",4);//returns 3
list.lastIndexOf("X");// returns -1
6.4返回列表索引的数据
at成员函数用于取出列表中对应的数据,参数为数据的索引值!
const T &QList::at(int i)const
遍历输出列表中的数据
/*构建一个列表类*/
QList<qint32>my_list;/*向列表中填充数据*/
my_list<<123<<456<<789;/*打印出列表中的数据*/for(int i=0;i<my_list.count();i++){//取出列表中指定的值qDebug()<<my_list.at(i);}
6.5其他常用函数接口
1、获取列表中节点的个数
int QList::count()const
2、判断列表是否为空
bool QList::isEmpty()const
3、删除指定数据值
int QList::removeAll(const T &value)
删除列表中出现的所有值并返回删除的条目的数量
4、删除列表的第一项数据
void QList::removeFirst()
5、删除指定索引位置的值
void QList::removeAt(int i)
7.元对象系统
元对象系统最主要的一个功能就是实现信号和槽,窗体和控件对象之间的沟通一般都使用信号和槽,Qt元对象系统实现了对象之间的通信机制信号和槽,并提供了运行时类型信息和动态属性系统。元对象系统是Qt类库独有的功能,是Qt对标准C++的扩展。
Qt中的元对象系统和标准C++系统的区别:
1、支持对象间使用信号与槽的机制进行通信
2、动态对象转化
3、可潮汛可设计的对象属性
4、层次结构可查询的对象树
5、安全的指针管理
6、支持国际化的文本转化
7、支持多任务定时器
8、事件和事件过滤器
7.1使用元对象系统
1、Qt的元对象系统基于如下三件事情:
1)QObject宏为所有需要利用元对象系统的对象提供了一个基类。Qt的窗体和控件最顶层的基类都是QObject.
2)Q_OBJECT,通常可以声明在类的私有段中,让该类可以使用元对象的特征,比如动态属性,信号与槽。
所有QObject的派生类再官方文档中都推荐在头文件中放置宏Q_OBJECT,建立工程的时候自动生成的类声明已经自动加入了Q_OBJECT的声明。
3)元对象编译器(moc)为每个QObject子对象自动生成必要的代码来实现元对象特征。
moc工具会读入C++的源文件,如果它发现了一个或者多个声明了Q_OBJECT宏的类,它就创建另一个C++源文件,为每个类生成包含元对象实现的代码。这些编译生成的源文件通常都已经被包含到类的源文件中或者和类的实现同时被编译和链接。
dialog.h中Q_OBJECT声明:
2、元对象系统除了提供信号和槽机制用于对象之间的通信,还提供了一些其他的特性
1)返回当前类对象关联的元对象(meta-object)。
QObject::metaObject()
2)返回当前对象的类名称字符串,而不需要C++编译器原生的运行时类型信息(run-time type information,RTTI)支持。
QMetaObject::className()
3)函数判断当前对象是否从某个基类派生,判断某个基类是否位于从QObject到对象当前类的继承树上。
QObject::inherits()
4)函数负责翻译国际化字符串,因为Qt5规定源文件字符编码是UTF-8,所以这两个函数现在功能是一样的。
QObject::tr()
QObject::trUtf8()
5)动态设置和获取属性,都是通过属性名称字符串来操作
QObject::setProperty()和QObject::property()
6)构建一个当前类的新实例对象。
QMetaObject::newInstance()
7.2信号与槽机制
信号槽机制与Windows下消息机制类似,消息机制是基于回调函数,Qt中用信号与槽来代替函数指针,使程序更安全简洁。
信号和槽用于对象间的通讯,信号/槽机制是Qt的一个核心特征。在图像用户界面编程中,我们经常通过信号槽将一个窗口部件的一个变化通知另一个窗口部件。
1、信号
当对象改变状态时候,信号就由该对象发送(emit)出去,而且对象只负责发送信号,它不知道另一端是谁在接收这个信号,这样就做到了真正的信息封装,能确保对象被当做一个真正的软件组件来使用。
2、槽
用于接收信号,而且槽只是普通的对象成员函数,一个槽并不知道是否有任何信号与自己相连接。而且对象并不了解具体的通信机制。
3、信号与槽连接
所有从QObject或其子类(例如Qwidget)派生的类都能够包含信号和槽。因为信号与槽的连接是通过QObject的connect()成员函数来实现的。
实例:
connect(sender,SIGNAL(signal),receiver,SLOT(slot));
其中sender与receiver是指向对象的指针,SIGNAL()与SLOT()是转换信号与槽的宏。
4、特点
一个信号可以连接多个槽,当信号发射时,会以不确定的顺序一个接一个的调用各个槽,多个信号可以连接同一个槽,即无论是哪一个信号被发射,都会调用这个槽。信号直接可以相互连接,发射第一个信号时,也可以发射第二个信号。
5、注意的问题
信号与槽机制与普通函数的调用一样,如果使用不当的话,在程序执行时也有可能产生死循环。因此,在定义槽函数时一定要注意避免间接形成无线循环,即在槽中再次发射接收到的同样信号。信号和槽的参数个数与类型必须一致,并且信号与槽函数都没有返回值。
7.3信号与槽手动关联
1)新建一个工程,在UI界面托一个按钮控件:实现点击按钮发送一个信号,按钮的槽函数中弹出一个对话框。
2)先打开QtCreator,新建一个Qt Widgets Application项目,基类选择Widget,其他默认即可。注意:在选择文件保存的路径的时候,一定不能有中文!!!
这里我们取项目名称为hands_signal
3)点击确认,输入项目名称hands_signal,选择不带中文的路径,再点击下一步。
4)在Details中选择Qwidget,其他默认不变,点击下一步,点击完成。
5)项目就创建完成,项目基本组成是由pro文件,.h文件,.cpp文件,.ui文件组成。
6)然后双击ui文件,把push Button拖拽到界面上
7)打开widget.h文件,在类中加上槽函数的声明代码
public slots://槽函数声明的标志voidpushButton_clicked();//声明槽函数
8)在widget.cpp问价中,在文件最下面编写槽函数代码,在槽函数里用到了弹出消息框的代码,还需要添加一个==#include==头文件
//槽函数定义代码,与普通成员函数写法一样,没有返回值void Dialog::pushButton_clicked(){
QMessageBox::information(NULL,"信号与槽函数","信号接收成功");}
9)添加槽函数与信号关联代码
//添加信号与槽关联代码,必须放在setupUi后面connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(pushButton_clicked()));
参数解析:
1)ui->pushButton:发送信号的对象指针名称(就是上异步在UI设计界面添加的按钮控件的对象名称,鼠标选中控件右键可以修改按钮的对象名称)。
2)SIGNAL(clicked()):clicked()函数是按钮支持的点击信号。SIGNAL()是转换信号的宏。
3)this:表示接收信号的对象指针
4)SLOT(pushButton_clicked()):pushButton_clicked()函数是槽函数的名称,SLOT()是转换槽函数的宏。
10)保存+运行
7.4信号与槽函数自动关联
自动关联不用手写connect函数,通过自动命名槽函数的方式来编写代码,自动关联的要求是槽函数根据源头的对象名(指针)和信号名称来命名,元对象系统可以实现自动connnect功能。这对窗体的设计非常方便,如果我们窗体里拖了10个按钮,手写connect函数,会非常麻烦,通过自动关联的方式,这些connect函数代码全可以省略,我们只需要关注如何实现槽函数的功能即可。
创建项目就不重复了,创建一个Widget的基类项目,项目名称为auto_signal。
1)右键PushButton按钮,选择转到槽,选择clicked()信号,就能自动生成代码。
2)自动生成的槽函数的代码,并且自动关联信号与槽函数
3)在Widget.h中自动生成函数的声明
4)在按钮槽函数里添加弹出的对话框代码,需要添加**#include**的头文件
void Widget::on_pushButton_clicked(){
QMessageBox::information(NULL,"信号与槽函数学习","信号接收成功");}
5)保存+运行
7.4.1槽函数的命名规则
必须遵循以下的规则
void on_对象名_信号名(信号名可能的参数)
例如:
on_pushButton_cliked()这个槽函数
按钮对象名为:pushButton,信号为clicked()。
7.4.1由uic和moc等工具自动生成
项目hands_signal为例,项目存放在C:\Users\72916\Desktop\MyQt路径下,编译模式位Debug模式。
那么在C:\Users\72916\Desktop\MyQt\build-hands_signal-Desktop_Qt_5_14_2_MinGW_64_bit-Debug路径下就可以看见ui_widget.h的文件
我们打开这个文件里面有一个 void setupUi(QWidget *Widget)函数。在setupUi函数末尾有一个
QMetaObject::connectSlotsByName(Widget);函数,该函数就是完成最后的自动关联,这是元对象系统包含的功能,根据对象名、信号名与
on_对象名_信号名(信号参数)
格式的槽函数进行自动匹配关联。
当然我们也可以通过帮助手册查看槽函数的说明
7.5connect语法格式说明
前面我们使用的是自动关联的方法,将信号与槽进行关联,使用方便,但是涉及到多个窗体的时候,就比较麻烦,比如A窗体私有按钮控件与B窗体私有消息框函数互相关联信号与槽函数的时候,这个由于有权限限制,不能自动关联,自动关联一般用于一个窗体之内的控件关联,其他很多情况都需要手动编写connect,所以要了解一次啊connect函数的语法,了解异常怎么传递参数
常见的两种写法:
1、与QT4兼容的写法格式
QObject::connect(const QObject *sender,constchar*signal,const QObject *receiver,const*method,Qt::connection type=Qt:QutoConnection)
参数:
1)const QObject *sender:信号源的对象指针(必须是实际存在的对象)
2)const char *signal:发送的信号。需要使用
SIGNAL
宏进行包装
3)const QObject *receiver:接收对方的对象指针(必须是实际存在的对象)
4)const *method:接收方的槽函数。需要使用
SLOT
宏进行包装。
5)Qt::connection type:该参数在多线程编程的时候才会有区别。
对于单线程,关联一般用直连类型(Qt::DirectConnection),信号一触发,对应槽函数立即就被调用执行;对于多线程程序,跨线程的关联一般用入队关联(Qt::QueuedConnection),信号触发后,跨线程的槽函数被加入时间处理队列里面执行,避免干扰接收线程里的执行流程。Qt::AutoConnection会自动根据源头对象和接收对象所属的线程来处理,默认都用这种类型的关联,对于多线程程序这种关联也是安全的。
这种句式的可读性很好,信号与槽的标识也很清晰,但是connect函数参数里的signal和method(槽函数)都是char*字符串类型,这种语法格式的connect函数是根据信号和槽函数的字符串名称关联的,不具备编译时类型检查,信号与槽函数都是字符串,参数类型在编译时都不知道,关联出错只在运行时才会体现出来。
关联用法实例:
QLabel *label = new QLabel;
QScrolBar *scrollBar=new QScrollBar;
QObject::connect(scrollBar,SIGNAL(valueChanged(int)),label,SLOT(setNum(int)));
2、QT5新出现的格式写法
QObject::connect(const QObject *sender,PointerToMemberFunction signal,const QObject *receiver,PointerToMemberFunction method,Qt::ConnectionType type =Qt::AutoConnection)
新写法用的是
PointerToMemberFunction
,这个类型名称是不存在的,只是在文档里面显示,实际使用的是模板函数,需要注意的是信号与槽的两个形参类型必须一致。
关联用法实例:
QLabel *label = new QLabel;
QLineEdit *lineEdit = new QLineEdit;
QObject::connect(lineEdit,&QLineEdit::textChanged,label,&QLabel::setText);
7.6解除信号槽关联
如果在某些时候不需要用到信号与槽函数的关联关系,可以使用disconnect函数解除之前的关联关系。disconnect函数与connect函数功能相反,两个函数的参数差不多。
1、兼容QT4的语法格式
bool QObject::disconnect(const QObject *sender,constchar*signal,const QObject *receiver,constchar* method)
2、QT5新语法格式
bool QObject::disconnect(const QObject *sender,PointerToMemberFunction signal,const QObject *receiver,PointerToMemberFuntion method)
通过disconnect函数的返回值可以判断解除关联是否执行成功。成功返回true,失败返回false。
3、两种解除关联方式示例
QObject::disconnect(ui->lineEdit,SIGNAL(textEdited(QString)),ui->label,SLOT(setText(QString)));
QObject::disconnect(lineEdit,&QLineEdit::textChanged,label,&QLabel::setText);
7.7自定义信号与槽
1)使用自定义的信号和槽,需要注意以下几点:
- 类的声明中必须包含Q_OBJECT宏
- 信号只需要声明不需要实现函数实体
- 发射信号使用emit关键字
- 自定义槽函数的实现与普通成员函数的实现方式一样
2)槽函数声明方式示例
class Widget : public QWidget
{
Q_OBJECT
public:Widget(QWidget *parent = nullptr);~Widget();
public slots://槽函数声明的标志voidpushButton_clicked();//声明槽函数
signals:voidvaluestring();//信号的声明voidvalueChange(int newValue);//带参数的声明
private:
Ui::Widget *ui;};
3)发送信号示例
emit valueChanged;//不带参数
emit valuestring("12345");//带参数
7.8pro工程标准写法
在编译QT的时候需要使用一个qmake工具命令来生成一个Makefile文件。手写Makefile是比较困难而且容易出错,尤其在进行跨平台开发时必须针对不同平台分别编写Makefile,会增加跨平台开发复杂度与困难度。qmake会根据工程文件(.pro)里面的信息自动生成适合平台的Makefile。qmake包含额外的功能来实现Qt开发,如自动包含moc和uic的编译规则,QT Creator的左边“项目”选项里面查看当前项目的构建目录和构建步骤。
虽然QT Creator可以自动生成pro文件,有些时候需要用到外带的链接库或者使用QT其他一些模块就需要手动修改pro文件,在开发QT程序之前掌握pro文件的写法是非常有必要的。
1、注释
pro文件中的注释由#号表示,只支持单行注释:从#号开始到这一行结束。
2、QT核心模块支持
pro文件中QT变量保存了当前项目支持的模块:模块之间使用空格隔开。“+=”符号表示追加,不会覆盖之前的值,比“=”更安全。
QT += core gui
3、
TARGET
变量指定生成的应用程序名称
TARGET=SIGNAL
4、模板变量
TEMPLATE
指定当前pro文件生成那种Makefile。
app表示建立一个应用程序的Makefile,这就是默认值。
lib表示建立一个库的Makefile。
示例:
TEMPLATE=app
5、
SOURCES
变量指定需要编译的源文件
示例:
SOURCES+=main.cpp widget.cpp
注意:换行可以用‘\’来表示。
6、
HEADERS
变量指定需要编译的头文件
HEADERS+= widget.h
7、
FORMS
变量指定需要编译的头文件
示例:
FORMS+= widget.ui
8、
RESOURCES
变量指定需要编译的qrc资源文件
示例:
RESOURCES+=\
images/images.qrc
9、
RC_FILE
变量指定windows下专用的rc资源文件。
示例:
RC_FILE+=main/main_ico.rc
10、
INCLUDEPATH
变量指定头文件的搜索路径
INCLUDEPATH+=$$PWD/install/include/
11、
LIBS
变量指定库搜索路径。在QT工程中使用到第三方函数接口,既可以指定库路劲。
LIBS+=$$PWD/install/libopencv_calib3d2413.dll
12、
DESTDIR
变量指定生成的可执行文件存放的目录
DESTDIR=bin
13、指定编译生成的一些临时文件存放的目录
示例:
#指定moc命令将含Q_OBJECT的头文件转换成成标准的.h文件的存放目录
MOC_DIR=temp/moc
#指定roc命令将.qrc文件转换成qrc_.*h文件的存放目录
RCC_DIR=temp/rcc
#指定uic命令将.ui文件转化成ui_*.h文件的存放的目录
UI_DIR=temp/ui
#指定目标文件(obj)的存放目录
OBJECTS_DIR=temp/obj
7.9区分运行平台
实际的项目中,都会在不同的平台上进行编译运行。可能不同平台上所需要使用的一些文件有区别,这种情况需要在pro文件中做平台区分。
win32:INCLUDEPATH+=C:/mylibs/extra
unix:INCLUDEPATH+=/home/user/extra
win32
{
INCLUDEPATH+=C:/mylibs/extra
}
unix
{
INCLUDEPATH+=/home/user/extra
}
8.一个pro文件编写实例
QT +=core gui network
QT +=serialport #支持串口模块
QT +=multimedia
QT +=multimediawidgets
QT +=network
QT += xml
greaterThan(QT_MAJOR_VERSION,4): QT+=widgets
TARGET=QT_home
TEMPLATE= app
SOURCES += main.cpp\
window/window.cpp \
luart/uart.cpp \
video/viode_cam.cpp \
TCP_server/tcp_server_my.cpp\
lTcpClient/tcp_client.cpp \
DNS_to_IPaddress/dns_to_ipaddress.cpp\
lweather/weather.cpp \
get_time/get_stdtime.cpp \
Create_QRcode/create_qrcode.cpp \
lget_identity_infolidentity_info.cpp \
get_phone_number_address/phone_address.cpp
HEADERS +=\
window/window.h \
luart/uart.h \
video/viode_cam.h \
TCP_server/tcp_server_my.h \
TcpClient/tcp_client.h \
DNS_to_IPaddress/dns_to_ipaddress.h \
weather/weather.h \
get_time/get_stdtime.h \
Create_QRcode/create_qrcode.h \
get_identity_infolidentity_info.h \
get_phone_number_address/phone_address.h
FORMS+=\
window/window.ui \
\uart/uart.ui \
video/viode_cam.ui \
TCP_server/tcp_server_my.ui \
TcpClient/tcp_client.ui \
DNS_to_IPaddress/dns_to_ipaddress.ui \
weather/weather.ui \
get_time/get_stdtime.ui \
Create_QRcodelcreate_qrcode.ui \
get_identity_info/identity_info.ui \
get_phone_number_address/phone_address.ui
CONFIG += mobility
MOBILITY=
RESOURCES+=\
images/images.qrc
DISTFILES+=
MOC_DIR =temp/moc
RCC_DIR =temp/rcc
UI_DIR =temp/ui
OBJECTS_DIR =temp/obj
DESTDIR = bin
win32:RC_FILE= main/main_ico.rc
win32 #windows平台下包含
{
INCLUDEPATH+=$$PWD/install/include/
INCLUDEPATH+=$$PWD/install/include/opencv
INCLUDEPATH+=$$PWD/install/include/opencv2
LIBS+=$$PWD/install/x86/mingw/lib/libopencv_calib3d2413.dll.a
}
unix #linxu平台和unix平台下包含
{
INCLUDEPATH+=/install/include/
INCLUDEPATH+=/install/include/opencv
INCLUDEPATH+=/install/include/opencv2
LIBS+=/install/lib/libopencv_calib3d2413.so
}
9.QByteArray字节数组介绍
9.1QByteArray类基本使用说明
QByteArray类提供了一个字节数组。
QByteArray可用于存储原始字节(包括‘\0’)和传统的8位‘\0’终止字符串。使用QByteArray比使用const char*方便得多,因为QByteArray始终确保数据后面跟着’\0’终止符,并使用隐式共享(写时复制)来减少内存使用并避免不必要的数据复制。
除了QByteArray之外,Qt还提供了QString类来存储字符串数据。对于大多数目而言,QString是常用的类。它存储16位Unicode字符,使你可以轻松地在应用程序中存储非ASCII/非拉丁字母字符。此外,QString在整个Qt API中都有使用。QByteArray适用的两种主要情况是何时需要存储原始二进制数据,何时需要对内存进行保存(例如:使用Qt for Embedded Linux)。
初始化QByteArrat的一种方法是将const char *传递给它的构造函数。例如,下面的代码创建一个包含数据“Hello”的大小为5字节数组。
QByteArray ba("Hello");
尽管size()是5,但字节数组在末尾还保留了一个额外的’\0’字符,因此,如果使用了一个函数来请求指向底层数据的指针(例如调用data()),则指向的数据保证以‘\0’结尾。
另一种方法是使用resize()设置数据的大小并且初始化每个字节的数据字节.QByteArray使用基于0索引,就像C++数组一样,要访问特定索引位置的字节,可以使用
operator[]()
。在非常量字节数组上,
operator[]()
返回可以在赋值左侧使用的字节的引用。
QByteArray ba("Hello");
ba.resize(5);
ba[0]=0x3c;
ba[1]=0xb8;
ba[2]=0x64;
ba[3]=0x18;
ba[4]=0xca;
对于只读访问,另一种语法是使用at();
for(int i=0;i<ba.size();++i){if(ba.at(i)>='a'&&ba.at(i)<='f')
cout<<"Found character in range[a-f]"<<endl;}
at()比
operator[]()
更快,因为它永远不会导致发生深层复制。
要一次提取多个字节,请使用left(),right(),或者mid()。
QByteArray可以嵌入‘\0’字节。size()函数总是返回整个数组的大小,包括嵌入的’\0’字节,但不包括由QByteArray添加的终止’\0’。
例如:
QByteArray bal("cal\0r\0t");qDebug()<<bal.size();//return 3, qDebug()<<bal.constData();//return cal
QByteArray bal1("cal\0r\0t",4);qDebug()<<bal1.size();//return 4 qDebug()<<bal1.constData();//return calconstchar cart[]={'c','a','l','\0','r','\0','t'};
QByteArray bal3(QByteArray::fromRawData(cart,6));qDebug()<<bal3.size();//return 6qDebug()<<bal3.constData();return cal
如果要获取数据的长度并排除第一个’\0’字符,请在字节数组上调用qstrlen()。
调用resize()之后,新分配的字节具有未定义的值。要将所有字节设置为特定值,请调用fill()。
要获取指向实际字符的指针,请调用data()或constData()。这些函数返回一个指向数据开头的指针。该指针保证保持有效,直到QByteArray上调用非const函数为止,除非QByteArray是从原始数据创建的,否则也保证数据以’\0’字节结尾,这个’\0’字节也是由QByteArray自动提供,不计入size()。
QByteArray 提供了修改字节数据的以下基本函数:append(),prepend(),insert(),replace()和 remove()。
实例:
QByteArray x("ship");
QByteArray y("air");
x.prepend(y);// x == "airship"
QByteArray x("free");
QByteArray y("dom");
x.append(y);// x == "freedom"
QByteArray x("Say yes!");
QByteArray y("no");
x.replace(4,3, y);// x == "Say no!"
replace()和remove()函数的前两个参数是指要开始搽除的位置和应该搽除的字节数。
将数据源附加到非空数组时,数组将被重新分配并将数据赋值到数组。通过调用 reserve()来预防分配一定数量的内存,从而避免此行为。你也可以调用 capacity()来找出 QByteArray 实际分配了多少内存。
通常的要求是从字节数组中删除空格字符(‘\ n’,'\ t’等)。如果你想从 QByteArray 的两端删除空格,使用trimmed()。如果要从两端删除空格并用字节数组中的单个空格字符替换多个连续的空格,请使用 simplified()。
如果要查找 QByteArray 中特定字符或子字符串的所有匹配项,请使用 indexOf()或 lastIndexOf()。前者从一个给定的索引位置开始搜索,后者向后搜索。如果他们找到了,它们都会返回字符或子字符串的索引位置;否则,它们返回-1。例如,下面是一个典型的循环,它查找所有出现的特定子字符串:
QByteArray x("sticky question");
QByteArray y("sti");
x.indexOf(y);// returns 0
x.indexOf(y,1);// returns 10
x.indexOf(y,10);// returns 10
x.indexOf(y,11);// returns -1
QByteArray x("crazy azimuths");
QByteArray y("az");
x.lastIndexOf(y);// returns 6
x.lastIndexOf(y,6);// returns 6
x.lastIndexOf(y,5);// returns 2
x.lastIndexOf(y,1);// returns -1
如果你只是想检查 QByteArray 是否包含特定的字符或子字符串,请使用 contains()。如果要查明字节数组中出现特定字符或子字符串的次数,请使用 count()。如果要将所有特定值替换为另一个值,请使用两个参数 replace()重载之一。
QByteArrays 可以使用重载操作符(比如 operator <(),operator <=(),operator ==(),operator> =()等进行比较。该比较仅基于字符的数字值。 QString ::localeAwareCompare()是排序用户界面字符串的更好选择。
QByteArray 区分了空字节数组和空字节数组。空字节数组是一个字节数组,它使用QByteArray 的默认构造函数或通过将(const char *)0 传递给构造函数来初始化。空字节数组是大小为 0 的任何字节数组。空字节数组始终为空,但空字节数组不一定为空:
QByteArray().isNull();// returns trueQByteArray("").isNull();// returns falseQByteArray("abc").isNull();// returns false
QByteArray().isEmpty();// returns trueQByteArray("").isEmpty();// returns trueQByteArray("abc").isEmpty();// returns false
除了 isNull()以外,所有函数都将空字节数组视为空字节数组。例如,data()返回一个指向空字节数组(不是空指针)的’\ 0’字符的指针,并且 QByteArray()将等于 QByteArray(“”)。建议始终使用 isEmpty()并避免使用 isNull()。
9.2设置数组字节大小
void QByteArray::resize(int size)
实例:
QByteArray data;//创建字符数组
data.resize(80);//指定字节大小
9.3返回数组大小
int QByteArray::length()constint QByteArray::size()constint QByteArray::count()const
实例:
QByteArray da;//创建字符数组
da.resize(1024);//指定字节大小
da.clear();//清楚字节数组的内容并使其为空
da.append("123456789");qDebug()<<da.size();//结果为9qDebug()<<da.length();//结果为9
9.4将数据转为其他类型
double QByteArray::toDouble(bool *ok = nullptr)constfloat QByteArray::toFloat(bool *ok = nullptr)const
QByteArray QByteArray::toHex()constint QByteArray::toInt(bool *ok = nullptr,int base =10)constlong QByteArray::toLong(bool *ok = nullptr,int base =10)const
qlonglong QByteArray::toLongLong(bool *ok = nullptr,int base =10)const
实例:
QByteArray string("1234.56");double a = string.toDouble();// a == 1234.56
9.4将数据转为C语言的字符指针返回
constchar* QByteArray::data()const
9.5数组数据的追加
相关函数:
QByteArray &prepend(char c);
QByteArray &prepend(int count,char c);
QByteArray &prepend(constchar*s);
QByteArray &prepend(constchar*s,int len);
QByteArray &prepend(const QByteArray &a);
QByteArray &append(char c);
QByteArray &append(int count,char c);
QByteArray &append(constchar*s);
QByteArray &append(constchar*s,int len);
QByteArray &append(const QByteArray &a);
实例:
QByteArray da;//创建字符数组
da.resize(1024);//指定字节大小
da.clear();//清除字节数组的内容并使其为空。
da.append("123");
da.append("456");
da.append("789");qDebug()<<da;//结果 123456789
9.6清除数组数据为指定值
QByteArray &fill(char c,int size =-1);//赋值为指定值 voidclear();//将数组清除为 0
实例:
QByteArray da;//创建字符数组
da.resize(1024);//指定字节大小
da.fill('8');//将数组整体空间数据赋值为指定数据’8’qDebug()<<da;
9.7数组数据的插入
相关函数:
QByteArray &insert(int i,char c);
QByteArray &insert(int i,int count,char c);
QByteArray &insert(int i,constchar*s);
QByteArray &insert(int i,constchar*s,int len);
QByteArray &insert(int i,const QByteArray &a);
实例:
QByteArray da;//创建字符数组
da.resize(1024);//指定字节大小
da.clear();//清除字节数组的内容并使其为空。
da.append("123");
da.append("456");
da.append("789");
da.insert(2,"abcd");//从第 2 个位置插入数据qDebug()<<da;//结果"12abcd3456789"
9.8删除指定位置指定长度的数据
QByteArray &remove(int index,int len);
实例:
QByteArray All_data;//创建字符数组
All_data.resize(1024);//指定字节大小
All_data.clear();//清除字节数组的内容并使其为空。
All_data.append("123");
All_data.append("456");
All_data.append("789");
All_data.remove(3,3);//从第 3 个位置删除 3 个数据qDebug()<<All_data;//结果"123789"
9.9替换指定位置的数据
相关函数:
QByteArray &replace(int index,int len,constchar*s);
QByteArray &replace(int index,int len,constchar*s,int alen);
QByteArray &replace(int index,int len,const QByteArray &s);
QByteArray &replace(char before,constchar*after);
QByteArray &replace(char before,const QByteArray &after);
QByteArray &replace(constchar*before,constchar*after);
QByteArray &replace(constchar*before,int bsize,constchar*after,int asize);
QByteArray &replace(const QByteArray &before,const QByteArray &after);
QByteArray &replace(const QByteArray &before,constchar*after);
QByteArray &replace(constchar*before,const QByteArray &after);
QByteArray &replace(char before,char after);
实例:
QByteArray da;//创建字符数组
da.resize(1024);//指定字节大小
da.clear();//清除字节数组的内容并使其为空。
da.append("123456789");
da.replace(3,3,"abc");//将第 3 个位置后的 3 个数据替换为 abcqDebug()<<da;//结果"123abc789"
9.10数组数据查找
相关函数:
int QByteArray::indexOf(const QByteArray &ba,int from =0)const
返回此字节数组中第一个出现字节数组 ba 的索引位置,从索引位置向前搜索。 如果找不到 ba,则返回-1。
QByteArray x("sticky question");
QByteArray y("sti");
x.indexOf(y);// returns 0
x.indexOf(y,1);// returns 10
x.indexOf(y,10);// returns 10
x.indexOf(y,11);// returns -1
9.11去除空白字符
QByteArray QByteArray::simplified()const
返回一个从开始和结束中删除空白的字节数组,其中每个内部空白序列都用一个空格替换。
空白表示标准 C ++ isspace()函数在 C 语言环境中返回 true 的任何字符。
这包括在 ASCII 语言环境中的 ASCII
isspace()函数返回 true。 这包括 ASCII 字符’\ t’,‘\ n’,‘\ v’,‘\ f’,‘\ r’和’ '。
QByteArray QByteArray::trimmed()const
返回从开始和结束删除空白的字节数组。
空白表示标准 C ++ isspace()函数在 C 语言环境中返回 true 的任何字符。 这包括 ASCII 字符’\ t’,‘\ n’,‘\ v’,‘\f’,‘\ r’和’ '。
实例:
QByteArray All_data;//创建字符数组
All_data.resize(1024);//指定字节大小
All_data.clear();//清空数组
All_data.append("*1024,24.56\n");
All_data.append("#12345678\n");qDebug()<<All_data;//原始结果:"*1024,24.56\n#12345678\n"qDebug()<<All_data.simplified();//去除所有的空白字符,结果:"*1024,24.56 #12345678"qDebug()<<All_data.trimmed();//去掉结尾的空白字符,结果:"*1024,24.56\n#12345678"
10QBuffer类介绍
10.1QBuffer基本使用介绍
说明: QBuffer 主要解决,char*类型的值。
QBuffer 类为 QByteArray 提供 QIODevice 接口。
QBuffer 允许你使用 QIODevice 接口访问 QByteArray。
QByteArray 被视为一个标准的随机访问文件。
例:
QBuffer buffer;char ch;
buffer.open(QBuffer::ReadWrite);
buffer.write("Qt rocks!");
buffer.seek(0);
buffer.getChar(&ch);// ch == 'Q'
buffer.getChar(&ch);// ch == 't'
buffer.getChar(&ch);// ch == ' '
buffer.getChar(&ch);// ch == 'r'
默认情况下,创建 QBuffer 时为您创建一个内部 QByteArray 缓冲区。 你可以通过调用 buffer()直接访问这个缓冲区。 你也可以通过调用 setBuffer()或者将你的数组传递给 QBuffer 的构造函数来将 QBuffer 与现有的QByteArray 一起使用。
调用 open()打开缓冲区。 然后调用 write()或 putChar()写入缓冲区,并通过 read(),readLine(),readAll()或getChar()从中读取。 Size()返回缓冲区的当前大小,你可以调用 seek()来寻找缓冲区中的任意位置。 当你完成访问缓冲区时,调用 close()关闭释放缓冲区。
以下代码片段显示了如何使用 QDataStream 和 QBuffer 将数据写入 QByteArray:
QByteArray byteArray;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::WriteOnly);
QDataStream out(&buffer);
out << QApplication::palette();
实际上,我们可以将应用程序的 QPalette 转换为一个字节数组。
以下是如何从 QByteArray 中读取数据的方法:
QPalette palette;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::ReadOnly);
QDataStream in(&buffer);
in >> palette;
QTextStream 和 QDataStream 还提供了便捷的构造函数,它们使用 QByteArray 并在后台创建 QBuffer。
当新数据到达缓冲区时,QBuffer 发射 readyRead()信号。通过连接这个信号,你可以在处理之前使用 QBuffer来存储临时数据。 每次新数据写入缓冲区时,QBuffer 也会发送 bytesWritten()。
另请参阅 QFile,QDataStream,QTextStream 和 QByteArray。
10.2数据读写实例
QByteArray All_data;//创建字符数组
All_data.resize(1024);//指定字节大小
All_data.clear();//清空数组
QBuffer buffer;
buffer.setBuffer(&All_data);//将 QByteArray 空间设置给 QBufferchar ch;
buffer.open(QBuffer::ReadWrite);//读写权限打开
buffer.write("123456789");
buffer.seek(0);//移动到空间第 0 个位置
buffer.getChar(&ch);// ch == '1'qDebug()<<ch;
buffer.getChar(&ch);// ch == '2'qDebug()<<ch;qDebug()<<buffer.readAll();//读取空间全部数据 ,结果:"3456789"
buffer.seek(0);//移动到空间第 0 个位置qDebug()<<buffer.readAll();//读取空间全部数据 ,结果:"123456789"
10.3数据处理一行的数据
QByteArray All_data;//创建字符数组
All_data.resize(1024);//指定字节大小
All_data.clear();//清空数组
QBuffer buffer;
buffer.setBuffer(&All_data);//将 QByteArray 空间设置给 QBufferchar ch;
buffer.open(QBuffer::ReadWrite);//读写权限打开
buffer.write("123\n456\n789\n");
buffer.seek(0);//移动指针为到 0if(buffer.canReadLine())//判断是否可以读取一行数据{qDebug()<<buffer.readLine();//结果:"123\n"}
以下代码片段显示了如何使用 QDataStream 和 QBuffer 将数据写入 QByteArray:
QByteArray byteArray;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::WriteOnly);
QDataStream out(&buffer);
out << QApplication::palette();
实际上,我们可以将应用程序的 QPalette 转换为一个字节数组。
以下是如何从 QByteArray 中读取数据的方法:
QPalette palette;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::ReadOnly);
QDataStream in(&buffer);
in >> palette;
QTextStream 和 QDataStream 还提供了便捷的构造函数,它们使用 QByteArray 并在后台创建 QBuffer。
当新数据到达缓冲区时,QBuffer 发射 readyRead()信号。通过连接这个信号,你可以在处理之前使用 QBuffer来存储临时数据。 每次新数据写入缓冲区时,QBuffer 也会发送 bytesWritten()。
另请参阅 QFile,QDataStream,QTextStream 和 QByteArray。
10.2数据读写实例
QByteArray All_data;//创建字符数组
All_data.resize(1024);//指定字节大小
All_data.clear();//清空数组
QBuffer buffer;
buffer.setBuffer(&All_data);//将 QByteArray 空间设置给 QBufferchar ch;
buffer.open(QBuffer::ReadWrite);//读写权限打开
buffer.write("123456789");
buffer.seek(0);//移动到空间第 0 个位置
buffer.getChar(&ch);// ch == '1'qDebug()<<ch;
buffer.getChar(&ch);// ch == '2'qDebug()<<ch;qDebug()<<buffer.readAll();//读取空间全部数据 ,结果:"3456789"
buffer.seek(0);//移动到空间第 0 个位置qDebug()<<buffer.readAll();//读取空间全部数据 ,结果:"123456789"
10.3数据处理一行的数据
QByteArray All_data;//创建字符数组
All_data.resize(1024);//指定字节大小
All_data.clear();//清空数组
QBuffer buffer;
buffer.setBuffer(&All_data);//将 QByteArray 空间设置给 QBufferchar ch;
buffer.open(QBuffer::ReadWrite);//读写权限打开
buffer.write("123\n456\n789\n");
buffer.seek(0);//移动指针为到 0if(buffer.canReadLine())//判断是否可以读取一行数据{qDebug()<<buffer.readLine();//结果:"123\n"}
版权归原作者 最没脑子 所有, 如有侵权,请联系我们删除。