找回密码
 立即注册
  • QQ空间
  • 回复
  • 收藏

QT软件开发-第一章 pro工程标准写法&QByteArray字节数组&Qbuffer类介绍

admin 2019-4-12 05:44 420人围观 Qt相关

1.9 pro工程标准写法


我们在编译QT程序的时候需要使用一个qmake工具命令来生成一个Makefile文件。手写Makefile是比较困难而且容易出错,尤其在进行跨平台开发时必须针对不同平台分别撰写Makefile,会增加跨平台开发复杂性与困难度。qmake会根据工程文件(.pro)里面的信息自动生成适合平台的 Makefile。qmake包含额外的功能来方便 Qt 开发,如自动的包含moc 和 uic 的编译规则。QT Creator的左边“项目“选项里查看当前项目的构建目录和构建步骤(如图1-9-1所示)。



图1-9-1构建步骤

虽然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 mainwindow.cpp

6. HEADERS变量指定需要编译的头文件

示例:HEADERS  += mainwindow.h

7. FORMS变量指定需要编译的UI文件。

示例:FORMS    += mainwindow.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/

$$PWD:表示获取当前pro工程文件的路径(当前路径)。

11. LIBS变量指定库搜索路径。在QT工程中使用到第三方函数接口,就可以指定库路径。

示例:LIBS+=$$PWD/install/lib/libopencv_calib3d2413.dll

12. DESTDIR变量指定生成的可执行文件存放的目录。

示例:DESTDIR = bin

13. 指定编译生成的一些临时文件存放的目录

示例:

#指定moc命令将含Q_OBJECT的头文件转换成标准.h文件的存放目录

MOC_DIR= temp/moc  

#指定rcc命令将.qrc文件转换成qrc_*.h文件的存放目录

RCC_DIR= temp/rcc

#指定uic命令将.ui文件转化成ui_*.h文件的存放的目录

UI_DIR= temp/ui

#指定目标文件(obj)的存放目录

OBJECTS_DIR= temp/obj

14. 区分运行平台

实际项目中,都会在不同的平台上进行编译运行。可能不同平台上所需要使用的一些文件有区别,这种情况就需要在pro文件中做平台区分。

win32:INCLUDEPATH += C:/mylibs/extra

unix:INCLUDEPATH += /home/user/extra

或者:

win32

{

    INCLUDEPATH += C:/mylibs/extra

}

unix

{

    INCLUDEPATH += /home/user/extra

}

15. 一个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 \

    uart/uart.cpp \

    video/viode_cam.cpp \

    TCP_server/tcp_server_my.cpp \

    TcpClient/tcp_client.cpp \

    DNS_to_IPaddress/dns_to_ipaddress.cpp \

    weather/weather.cpp \

    get_time/get_stdtime.cpp \

    Create_QRcode/create_qrcode.cpp \

    get_identity_info/identity_info.cpp \

    get_phone_number_address/phone_address.cpp

HEADERS  += \

    window/window.h \

    uart/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_info/identity_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_QRcode/create_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

}

1.10 QByteArray字节数组介绍

1.10.1 QByteArray类基本使用说明


QByteArray类提供了一个字节数组。

QByteArray可用于存储原始字节(包括'\ 0')和传统的8位'\ 0'终止字符串。使用QByteArray比使用const char *方便得多。在幕后,它始终确保数据后面跟着'\ 0'终止符,并使用隐式共享(写时复制)来减少内存使用并避免不必要的数据复制。

除了QByteArray之外,Qt还提供了QString类来存储字符串数据。对于大多数目的而言,QString是常用的类。它存储16位Unicode字符,使你可以轻松地在应用程序中存储非ASCII /非拉丁字母字符。此外,QString在整个Qt API中都有使用。 QByteArray适用的两种主要情况是何时需要存储原始二进制数据,何时需要对内存进行保存(例如,使用Qt for Embedded Linux)。

初始化QByteArray的一种方法就是将const char *传递给它的构造函数。例如,下面的代码创建一个包含数据“Hello”的大小为5的字节数组:

QByteArray ba("Hello");

尽管size()是5,但字节数组在末尾还保留了一个额外的'\ 0'字符,因此如果使用了一个函数来请求指向底层数据的指针(例如调用data()),则指向的数据保证以'\ 0'结尾。

另一种方法是使用resize()设置数组的大小并初始化每个字节的数据字节。 QByteArray使用基于0的索引,就像C ++数组一样。 要访问特定索引位置的字节,可以使用operator []()。 在非常量字节数组上,operator []()返回可以在赋值左侧使用的字节的引用。 例如:

QByteArray ba;

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 ba1("ca\0r\0t");

ba1.size();                     // Returns 2.

ba1.constData();                // Returns "ca" with terminating \0.

QByteArray ba2("ca\0r\0t", 3);

ba2.size();                     // Returns 3.

ba2.constData();                // Returns "ca\0" with terminating \0.

QByteArray ba3("ca\0r\0t", 4);

ba3.size();                     // Returns 4.

ba3.constData();                // Returns "ca\0r" with terminating \0.

const char cart[] = {'c', 'a', '\0', 'r', '\0', 't'};

QByteArray ba4(QByteArray::fromRawData(cart, 6));

ba4.size();                     // Returns 6.

ba4.constData();                // Returns "ca\0r\0t" without terminating \0.

如果想要获取数据的长度并排除第一个'\ 0'字符,请在字节数组上调用qstrlen()。

调用resize()之后,新分配的字节具有未定义的值。 要将所有字节设置为特定值,请调用fill()。

要获取指向实际字符数据的指针,请调用data()或constData()。 这些函数返回一个指向数据开头的指针。 该指针保证保持有效,直到在QByteArray上调用非const函数为止。 除非QByteArray是从原始数据创建的,否则也保证数据以'\ 0'字节结尾。 这个'\ 0'字节由QByteArray自动提供,不计入size()。

QByteArray提供了修改字节数据的以下基本函数:append(),prepend(),insert(),replace()和remove()。

例如:

QByteArray x("and");

x.prepend("rock ");         // x == "rock and"

x.append(" roll");          // x == "rock and roll"

x.replace(5, 3, "&");       // x == "rock & roll"

Replace()和remove()函数的前两个参数是要开始擦除的位置和应该擦除的字节数。

将数据附加到非空数组时,数组将被重新分配并将新数据复制到它。你可以通过调用reserve()来预防分配一定数量的内存,从而避免此行为。你也可以调用capacity()来找出QByteArray实际分配了多少内存。

通常的要求是从字节数组中删除空格字符('\ n','\ t'等)。如果你想从QByteArray的两端删除空格,使用trimmed()。如果要从两端删除空格并用字节数组中的单个空格字符替换多个连续的空格,请使用simplified()。

如果要查找QByteArray中特定字符或子字符串的所有匹配项,请使用indexOf()或lastIndexOf()。前者从一个给定的索引位置开始搜索,后者向后搜索。如果他们找到它们,它们都会返回字符或子字符串的索引位置;否则,它们返回-1。例如,下面是一个典型的循环,它查找所有出现的特定子字符串:

QByteArray ba("We must be <b>bold</b>, very <b>bold</b>");

int j = 0;

while ((j = ba.indexOf("<b>", j)) != -1) {

  cout << "Found <b> tag at index position " << j << endl;

  ++j;

}

如果你只是想检查QByteArray是否包含特定的字符或子字符串,请使用contains()。如果要查明字节数组中出现特定字符或子字符串的次数,请使用count()。如果要将所有特定值替换为另一个值,请使用两个参数replace()重载之一。

QByteArrays可以使用重载操作符(比如operator <(),operator <=(),operator ==(),operator> =()等进行比较。该比较仅基于字符的数字值。 QString :: localeAwareCompare()是排序用户界面字符串的更好选择。

由于历史原因,QByteArray区分了空字节数组和空字节数组。空字节数组是一个字节数组,它使用QByteArray的默认构造函数或通过将(const char *)0传递给构造函数来初始化。空字节数组是大小为0的任何字节数组。空字节数组始终为空,但空字节数组不一定为空:

QByteArray().isNull();          // returns true

QByteArray().isEmpty();         // returns true

QByteArray("").isNull();        // returns false

QByteArray("").isEmpty();       // returns true

QByteArray("abc").isNull();     // returns false

QByteArray("abc").isEmpty();    // returns false

除了isNull()以外,所有函数都将空字节数组视为空字节数组。例如,data()返回一个指向空字节数组(不是空指针)的'\ 0'字符的指针,并且QByteArray()将等于QByteArray(“”)。建议始终使用isEmpty()并避免使用isNull()。

l 有关语言环境的注释

数字字符串转换

执行数字数据类型和字符串之间的转换的函数在C语言环境中执行,与用户的区域设置无关。使用QString在数字和字符串之间执行区域识别转换。

8位字符比较

在QByteArray中,大写和小写以及哪个字符大于或小于另一个字符的概念与语言环境有关。这会影响支持不区分大小写选项的函数或比较小写或大写参数的函数。如果两个字符串仅包含ASCII字符,则不区分大小写的操作和比较将是准确的。影响的函数contains(),indexOf(),lastIndexOf(),运算符<(),运算符<=(),运算符>(),运算符> =(),toLower()和toUpper()。

此问题不适用于QStrings,因为它使用Unicode的字符。

另请参阅QString和QBitArray。

1.10.2 设置数组字节大小


void QByteArray::resize(int size)

示例:

 QByteArray All_data;  //创建字符数组

 All_data.resize(888);   //指定字节大小


1.10.3 返回数组大小


int QByteArray::length() const

int QByteArray::size() const

int QByteArray::count() const

示例:

QByteArray All_data;  //创建字符数组

All_data.resize(1024); //指定字节大小

All_data.clear(); //清除字节数组的内容并使其为空。

All_data.append("123456789");

qDebug()<<All_data.size(); //结果: 9

qDebug()<<All_data.length(); //结果:9


1.10.4 将数据转为其他类型


double QByteArray::toDouble(bool * ok = 0) const

float QByteArray::toFloat(bool * ok = 0) const

QByteArray QByteArray::toHex() const

int QByteArray::toInt(bool * ok = 0, int base = 10) const

long QByteArray::toLong(bool * ok = 0, int base = 10) const

qlonglong QByteArray::toLongLong(bool * ok = 0, int base = 10) const

示例:

    QByteArray string("1234.56");

    double a = string.toDouble();   // a == 1234.56


1.10.5 将数据转为C语言的字符指针返回


const char * QByteArray::data() const


1.10.6 数组数据追加


相关函数:

QByteArray &prepend(char c);

QByteArray &prepend(int count, char c);

QByteArray &prepend(const char *s);

QByteArray &prepend(const char *s, int len);

QByteArray &prepend(const QByteArray &a);

QByteArray &append(char c);

QByteArray &append(int count, char c);

QByteArray &append(const char *s);

QByteArray &append(const char *s, int len);

QByteArray &append(const QByteArray &a);

示例:

QByteArray All_data;  //创建字符数组

All_data.resize(1024); //指定字节大小

All_data.clear(); //清除字节数组的内容并使其为空。

All_data.append("123");

All_data.append("456");

All_data.append("789");

qDebug()<<All_data;  //结果123456789

1.10.7 清除数组数据为指定值


QByteArray &fill(char c, int size = -1); //赋值为指定值  

void clear();  //将数组清除为0

示例:

QByteArray All_data;  //创建字符数组

All_data.resize(1024); //指定字节大小

All_data.fill('8');    //将数组整体空间数据赋值为指定数据’8’

qDebug()<<All_data;



1.10.8 数组数据插入


相关函数:

QByteArray &insert(int i, char c);

QByteArray &insert(int i, int count, char c);

QByteArray &insert(int i, const char *s);

QByteArray &insert(int i, const char *s, int len);

QByteArray &insert(int i, const QByteArray &a);

示例:

QByteArray All_data;  //创建字符数组

All_data.resize(1024); //指定字节大小

All_data.clear(); //清除字节数组的内容并使其为空。

All_data.append("123");

All_data.append("456");

All_data.append("789");

All_data.insert(2,"abcd");  //从第2个位置插入数据

qDebug()<<All_data;  //结果"12abcd3456789"

1.10.9 删除指定位置指定长度的数据


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"

1.10.10 替换指定位置的数据


相关函数:

QByteArray &replace(int index, int len, const char *s);

QByteArray &replace(int index, int len, const char *s, int alen);

QByteArray &replace(int index, int len, const QByteArray &s);

QByteArray &replace(char before, const char *after);

QByteArray &replace(char before, const QByteArray &after);

QByteArray &replace(const char *before, const char *after);

QByteArray &replace(const char *before, int bsize, const char *after, int asize);

QByteArray &replace(const QByteArray &before, const QByteArray &after);

QByteArray &replace(const QByteArray &before, const char *after);

QByteArray &replace(const char *before, const QByteArray &after);

QByteArray &replace(char before, char after);

示例:

QByteArray All_data;  //创建字符数组

All_data.resize(1024); //指定字节大小

All_data.clear(); //清除字节数组的内容并使其为空。

All_data.append("123456789");

All_data.replace(3,3,"abc"); //将第3个位置后的3个数据替换为abc

qDebug()<<All_data;  //结果"123abc789"

1.10.11 数组数据查找


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

1.10.12 去除空白字符


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"


1.11 QBuffer类介绍

1.11.1 QBuffer基本使用介绍


说明:  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。

1.11.2 数据读写示例


QByteArray All_data;   //创建字符数组

    All_data.resize(1024); //指定字节大小

    All_data.clear();      //清空数组

    QBuffer buffer;

    buffer.setBuffer(&All_data);  //将QByteArray空间设置给QBuffer

    char 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"

1.11.3 数据处理一行的数据


QByteArray All_data;   //创建字符数组

    All_data.resize(1024);   //指定字节大小

    All_data.clear();        //清空数组

    QBuffer buffer;

    buffer.setBuffer(&All_data);  //将QByteArray空间设置给QBuffer

    char ch;

    buffer.open(QBuffer::ReadWrite); //读写权限打开

    buffer.write("123\n456\n789\n");

    buffer.seek(0); //移动指针为到0

    if(buffer.canReadLine())//判断是否可以读取一行数据

    {

         qDebug()<<buffer.readLine(); //结果:"123\n"

    }

至此,第一章到此结束。

----------------------------------------------------------------------------------------------------------------------
我们尊重原创,也注重分享,文章来源于微信公众号:DS小龙哥 嵌入式技术资讯,建议关注公众号查看原文。如若侵权请联系qter@qter.org。
----------------------------------------------------------------------------------------------------------------------

鲜花

握手

雷人

路过

鸡蛋

yafeilinux和他的朋友们微信公众号二维码

微信公众号

专注于Qt嵌入式Linux开发等。扫一扫立即关注。

Qt开源社区官方QQ群二维码

QQ交流群

欢迎加入QQ群大家庭,一起讨论学习!

我有话说......