qt serialport android,Qt SerialPort 与 PyQt5 (三)

本文用于介绍 QIODevice 类,该类是 QSerialPort 的父类。

系统环境:Win10 64位

转载请注明出处:http://www.jianshu.com/u/5e6f798c903a

4.QIODevice 类

为了便于理解,这里给出本节内容的思维导图:( 本节后面的内容也遵循此结构 )

84ed6caae9e8

QIODevice.png

4.1 简介

QIODevice 类是 Qt 中所有 I/O 设备的基础接口类。

QIODevice 为支持数据块读写的设备 (如:QFile, QBuffer 和 QTcpSocket) 提供了通用实现和抽象接口。

QIODevice 属于抽象类,不能被实例化,但通常会使用由 QIODevice 定义的接口来提供设备共有的 I/O 特性。例如,Qt 的 XML 类运行在 QIODevice 指针上,以允许 XML 类可与各种设备( 如文件和缓存 )一同被使用。

在访问设备之前,必须调用 open() 函数,以设置正确的 OpenMode (如 ReadOnly 或 ReadWrite)。然后,可以调用 write() 或 putChar() 进行写入,或调用 read()、readLine()、readAll() 进行读取。完成操作后,调用 close() 关闭设备。

QIODevice 可识别两种设备类型(可调用 isSequential() 来确定设备的类型):

随机访问设备( random-access devices ),支持使用 seek() 来查找任意位置。通过调用 pos(),可获得在文件中的当前位置。QFile 和 QBuffer 便属于这类设备。

顺序设备( sequential devices ),不支持查找任意位置。数据必须被一次性读取。函数 pos() and size() 不适用于顺序设备。 QTcpSocket and QProcess 便属于这类设备。

当有可供读取的新数据时,QIODevice 会发出 readyRead() 信号(比如,网络上有新数据抵达时,或是有新数据被追加到正在读取的文件时)。bytesAvailable() 用于确定当前可供读取的字节数。为异步设备(如 QTcpSocket )编写程序时,通常会同时使用 bytesAvailable() 和 readyRead() ,因为异步设备的数据片段可能会在任意时间点到达。每当数据载荷被写入设备时,QIODevice 便会发射 bytesWritten() 信号。bytesToWrite() 用于确定当前等待写入的数据总量。

QIODevice 的某些子类属于异步子类,比如 QTcpSocket 和 QProcess 。这些子类的 I/O 函数(如 write() 、read() )总是立即返回,等控制权返回事件循环后,才会和设备本身进行通讯。QIODevice 还提供了相应的函数,以便强制 I/O 操作被立即执行,同时会阻塞调用线程,而不会进入事件循环。以下函数便具有这样的特性,但不要在事件循环中使用它们,或是在另外一个单独的线程中使用。

waitForReadyRead() - 该函数会在调用线程中挂起操作,直到有可供读取的新数据为止。

waitForBytesWritten() - 该函数在调用线程中挂起操作,直到一个数据载荷被写入到设备为止。

waitFor....() - 在 QIODevice 的子类中,针对设备特有的操作实现的阻塞函数。例如,例如, QProcess 有一个叫做 waitForStarted() 的函数,可在调用线程中挂起操作直到进程启动。

在主线程或 GUI 线程中调用以上函数,可能会导致用户界面冻结。例如:

QProcess gzip;

gzip.start("gzip", QStringList() << "-c");

if (!gzip.waitForStarted())

return false;

gzip.write("uncompressed data");

QByteArray compressed;

while (gzip.waitForReadyRead())

compressed += gzip.readAll();

通过继承 QIODevice,便可为自有 I/O 设备提供相同的接口。QIODevice 的子类仅需要实现受保护的 readData() 和 writeData() 函数。QIODevice 使用这两个函数来实现相关函数(如, getChar()、readLine() 和 write()),使操作更加便捷。QIODevice 还会为我们处理访问控制,因此如果调用了 writeDate(),则可以安全地假定设备以写模式打开。

像 QFile 和 QTcpSocket 这样的子类,会使用内存缓冲区来实现中间数据的存储。这种方式减少了访问设备( 这里的设备指 file、socket 等 )的次数,但这种方式通常非常慢。使用 getChar() 和 putChar() 这样的函数访问缓冲区,会更加快捷。因为这些函数在内存缓冲区中运行,而非直接运行在设备中。但是,某些 I/O 操作对缓冲区不起作用,例如:如果多个用户都打开了相同的设备并逐一读取每个字符,那么当用户打算读取各自所需的数据块时,它们最终可能会读取到相同的数据。出于此原因,QIODevice 允许允许向 open() 函数传递 Unbuffered 标志来忽略任何缓冲。在创建 QIODevice 的子类时,当设备在 Unbuffered 模式下被打开后,记得忽略任何缓冲区。

通常情况下,来自异步设备的数据流是片段华的,数据块可能会在任意时间点到达。要处理读取到的不完整的数据结构,可使用由 QIODevice 实现的事务处理机制。详细信息,请参阅 startTransaction() 及相关函数。

某些顺序设备支持通过多通道通讯。通道代表独立的数据流,拥有相互独立的发送顺序。一旦相应设备被打开,便可通过调用 readChannelCount() 和 writeChannelCount() 函数来确定通道的数量。需要切换通道时,请分别调用 setCurrentReadChannel() 和 setCurrentWriteChannel()。QIODevice 还提供了额外的信号,用于处理基于每个通道的异步通讯。

4.2 创建对象

QIODevice::QIODevice()

构建一个 QIODevice 对象。

QIODevice::QIODevice(QObject *parent)

使用给定的父对象构建一个 QIODevice 对象。

QIODevice::~QIODevice() [virtual]

该析构函数是虚拟的,QIODevice 属于抽象基类。该析构函数不会调用 close(),但是其子类的析构函数可能会调用。如果有疑虑,请在销毁 QIODevice 前调用 close()。

4.3 打开模式

enum QIODevice::OpenModeFlag 枚举配合 open() 函数使用,用于描述设备的打开方式。可用通过 openMode() 函数可查看设备的打开模式。

Constant

Value

Description

QIODevice::NotOpen

0x0000

设备没有被打开

QIODevice::ReadOnly<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值