Qt文档阅读笔记-QIODevice解析及Audio Example实例解析
目錄
?
QIODevice官方解釋及個人分析
Audio Example官方實例解析
?
QIODevice官方解釋及個人分析
QIODevice類是Qt中I/O設備的接口。
提供了讀和寫的接口,QIODevice是抽象的不能被實用化。
調用設備之前,要使用open()來設置打開方式(ReadOnly和ReadWrite)。可以使用write()或putChar()向設備寫數(shù)據(jù)
,同樣可以使用rad(),raedLine()或readAll()去讀設備。當不用的時候調用close()關閉操作。
QIODevice區(qū)分了兩種設備類型 隨機訪問設備 和 順序設備。
隨機訪問設備:使用seek()可以任意訪問位置,可以使用pos()定位文件的位置,QFile和QBuffer都是隨機訪問設備。
順序訪問設備:不能任意訪問位置,數(shù)據(jù)必須一次性讀取,pos()和size()在順序訪問設備里面都不能正常工作。
QTcpSocket和QProcess都是順序訪問設備。
可以使用isSequential()看看他屬于什么設備類型。
當能讀時會發(fā)出readyRead()信號。調用bytesAvailable()查看當前能讀取的字節(jié)數(shù)。向設備寫數(shù)據(jù)時會發(fā)射
bytesWritten()信號。調用bytesToWrite()來查看待寫入的字節(jié)數(shù)。
QIODevice的子類QTcpSocket和QProcess都是異步處理的,但也可以使用waitForReadyRead()和waitForBytesWritten
()去讓他阻塞。
這里可以看到QProcess這個順序訪問設備開啟一個外部進程,并且使用了阻塞的方式,如果這個調用是放在GUI線程里面的,那么肯定會有問題,界面肯定會卡住。
注意:這個問題一點要注意,在本人參與的項目中,很多人寫的程序,都喜歡用GUI線程去讀東西,一旦處理不好,就會造成阻塞。建議Qt開發(fā)經驗或技巧不足的朋友,多多使用線程去讀寫這些東西,不要使用GUI線程去做(其實在Qt中有很多方式和技巧可以在GUI線程里面操作,同時也不會阻塞GUI線程)
?
?
Audio Example官方實例解析
這里是官方的實例,我先把代碼貼上,因為版權占用太多,我把版權去掉了,但這個例子是Qt官方提供的,特產聲明(本人勵志做一個有節(jié)操的程序員,不僅要看破,而且要說破)
源碼如下:
widget.h
#ifndef WIDGET_H #define WIDGET_H#include <QtWidgets/QWidget> #include <QtCharts/QChartGlobal>QT_CHARTS_BEGIN_NAMESPACE class QLineSeries; class QChart; QT_CHARTS_END_NAMESPACEQT_CHARTS_USE_NAMESPACEclass XYSeriesIODevice;QT_BEGIN_NAMESPACE class QAudioInput; QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent = 0);~Widget();private:XYSeriesIODevice *m_device;QChart *m_chart;QLineSeries *m_series;QAudioInput *m_audioInput; };#endif // WIDGET_Hxyseriesiodevice.h
#ifndef XYSERIESIODEVICE_H #define XYSERIESIODEVICE_H#include <QtCore/QIODevice> #include <QtCharts/QChartGlobal>QT_CHARTS_BEGIN_NAMESPACE class QXYSeries; QT_CHARTS_END_NAMESPACEQT_CHARTS_USE_NAMESPACEclass XYSeriesIODevice : public QIODevice {Q_OBJECT public:explicit XYSeriesIODevice(QXYSeries * series, QObject *parent = 0);protected:qint64 readData(char * data, qint64 maxSize);qint64 writeData(const char * data, qint64 maxSize);private:QXYSeries *m_series; };#endif // XYSERIESIODEVICE_Hmain.cpp
#include <QtWidgets/QApplication> #include "widget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }widget.cpp
#include "widget.h" #include <QtMultimedia/QAudioDeviceInfo> #include <QtMultimedia/QAudioInput> #include <QtCharts/QChartView> #include <QtCharts/QLineSeries> #include <QtCharts/QChart> #include <QtWidgets/QVBoxLayout> #include <QtCharts/QValueAxis> #include "xyseriesiodevice.h"QT_CHARTS_USE_NAMESPACEWidget::Widget(QWidget *parent): QWidget(parent),m_device(0),m_chart(0),m_series(0),m_audioInput(0) {m_chart = new QChart;QChartView *chartView = new QChartView(m_chart);chartView->setMinimumSize(800, 600);m_series = new QLineSeries;m_chart->addSeries(m_series);QValueAxis *axisX = new QValueAxis;axisX->setRange(0, 2000);axisX->setLabelFormat("%g");axisX->setTitleText("Samples");QValueAxis *axisY = new QValueAxis;axisY->setRange(-1, 1);axisY->setTitleText("Audio level");m_chart->setAxisX(axisX, m_series);m_chart->setAxisY(axisY, m_series);m_chart->legend()->hide();m_chart->setTitle("Data from the microphone");QVBoxLayout *mainLayout = new QVBoxLayout;mainLayout->addWidget(chartView);setLayout(mainLayout);QAudioFormat formatAudio;formatAudio.setSampleRate(8000);formatAudio.setChannelCount(1);formatAudio.setSampleSize(8);formatAudio.setCodec("audio/pcm");formatAudio.setByteOrder(QAudioFormat::LittleEndian);formatAudio.setSampleType(QAudioFormat::UnSignedInt);QAudioDeviceInfo inputDevices = QAudioDeviceInfo::defaultInputDevice();m_audioInput = new QAudioInput(inputDevices,formatAudio, this);m_device = new XYSeriesIODevice(m_series, this);m_device->open(QIODevice::WriteOnly);m_audioInput->start(m_device); }Widget::~Widget() {m_audioInput->stop();m_device->close(); }xyseriesiodevice.cpp
#include "xyseriesiodevice.h" #include <QtCharts/QXYSeries>XYSeriesIODevice::XYSeriesIODevice(QXYSeries * series, QObject *parent) :QIODevice(parent),m_series(series) { }qint64 XYSeriesIODevice::readData(char * data, qint64 maxSize) {Q_UNUSED(data)Q_UNUSED(maxSize)return -1; }qint64 XYSeriesIODevice::writeData(const char * data, qint64 maxSize) {qint64 range = 2000;QVector<QPointF> oldPoints = m_series->pointsVector();QVector<QPointF> points;int resolution = 4;if (oldPoints.count() < range) {points = m_series->pointsVector();} else {for (int i = maxSize/resolution; i < oldPoints.count(); i++)points.append(QPointF(i - maxSize/resolution, oldPoints.at(i).y()));}qint64 size = points.count();for (int k = 0; k < maxSize/resolution; k++)points.append(QPointF(k + size, ((quint8)data[resolution * k] - 128)/128.0));m_series->replace(points);return maxSize; }這里只提下這個XYSeriesIODevice這個類,
此類為QIODevice的子類。
這里提出2個問題:
為毛要重寫readData()和writeData()這兩個函數(shù)?
為毛readDatat()里面是空的而writeData()這函數(shù)卻對QXYSeries進行了操作?
下面來依次回答這2個問題!
通過官方文檔得到readData()和writeData()為純虛函數(shù),所以一定要寫上去。
第二個問題,因為QAuidoInput::start(QIODevice *device)中把音頻數(shù)據(jù)發(fā)送到device中了,他是以寫入的形式發(fā)到device中的,內部肯定是有個回調,回調了writeData(),所以在那里面寫曲線即可。
?
?
總結
以上是生活随笔為你收集整理的Qt文档阅读笔记-QIODevice解析及Audio Example实例解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端笔记-Vue框架的基本认识
- 下一篇: RabbitMQ笔记-使用rabbitm