国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

07-2_Qt 5.9 C++開發(fā)指南_二進制文件讀寫(stm和dat格式)

這篇具有很好參考價值的文章主要介紹了07-2_Qt 5.9 C++開發(fā)指南_二進制文件讀寫(stm和dat格式)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1. 實例功能概述

除了文本文件之外,其他需要按照一定的格式定義讀寫的文件都稱為二進制文件。每種格式的二進制文件都有自己的格式定義,寫入數據時按照一定的順序寫入,讀出時也按照相應的順序讀出。例如地球物理中常用的 SEG-Y 格式文件,必須按照其標準格式要求寫入數據才符合這種文件的格式規(guī)范,讀取數據時也需要按照格式定義來讀出。
Qt 使用 QFile 和QDataStream 進行二進制數據文件的讀寫。QFile 負責文件的10 設備接口,即與文件的物理交互,QDataStream 以數據流的方式讀取文件內容或寫入文件內容。

本節(jié)以實例 samp7_2 演示二進制文件的讀寫,圖7-2 是程序運行的界面。

07-2_Qt 5.9 C++開發(fā)指南_二進制文件讀寫(stm和dat格式),# Qt 5.9 C++開發(fā)指南,qt,c++

實例以表格形式編輯一個數據表,采用 Model/View 結構,編輯后的數據保存為二進制文件,這與第 5.4 節(jié)的實例用純文本文件存儲數據不同。

根據 QDataStream 保存文件時使用的數據編碼的方式不同,可以保存為兩種文件。

(1)用Qt預定義編碼保存各種類型數據的文件,定義文件后綴為“.stm”。Qt 預定義編碼是指在寫入某個類型數據,如整形數、字符串等到文件流時,使用 Qt 預定義的編碼。可以將這種 Qt 預定義數據格式編碼類比于 HTML 的標記符,Qt 寫入某種類型數據時用了 Qt 預定義的標記符,讀出數據時,根據標記符讀出數據。使用 Qt 預定義編碼保存的流文件,某些字節(jié)是 QDataStream 自己寫入的,我們并不完全知道文件內每個字節(jié)的意義,但是用 QDataStream 可以讀出相應的數據。

(2)標準編碼數據文件,定義文件后綴為“.dat”。在將數據寫到文件時,完全使用數據的二進制原始內容,每個字節(jié)都有具體的定義,在讀出數據時,只需根據每個字節(jié)的定義讀出數據即可。

實例samp7_2具有如下功能:

  • 可以在表格內編輯數據,同樣的表格數據內容可以保存為兩種格式的文件,Qt 預定義編碼文件(stm 文件)和標準編碼文件 (dat 文件);

  • 界面上的表格數據可以修改,可以添加行、插入行、刪除行;

  • 可以讀取 stm 文件或 dat 文件,雖然文件格式不一樣,但對相同的界面數據表存儲的文件的實質內容是一樣的。

實例samp7_2的主窗口使用了 Model/View 結構、標準項數據模型 QStandardItemModel和選擇模型QItemSelectionModel,界面上使用了QTableView 組件,還有代理組件。這些涉及 Model/View的設計可參考第 5.4 節(jié)和 5.5 節(jié),這些設計在前述章節(jié)里已經介紹過,不是本節(jié)的重點,不再詳述。

為便于理解后面的程序,這里給出主窗口 MainWindow 類中自定義的一些變量和函數,具體如下(忽略了自動生成的一些定義):

//用于狀態(tài)欄的信息顯示
    QLabel  *LabCellPos;    //當前單元格行列號
    QLabel  *LabCellText;   //當前單元格內容

    QWIntSpinDelegate    intSpinDelegate; //整型數
    QWFloatSpinDelegate  floatSpinDelegate; //浮點數
    QWComboBoxDelegate   comboBoxDelegate; //列表選擇

    QStandardItemModel  *theModel;//數據模型
    QItemSelectionModel *theSelection;//Item選擇模型

    void    resetTable(int aRowCount);  //表格復位,設定行數
    bool    saveDataAsStream(QString& aFileName);//將數據保存為數據流文件
    bool    openDataAsStream(QString& aFileName);//讀取數據流文件

    bool    saveBinaryFile(QString& aFileName);//保存為二進制文件
    bool    openBinaryFile(QString& aFileName);//打開二進制文件

2. Qt預定義編碼文件的讀寫

2.1 保存為stm文件

先看文件保存功能,因為從文件保存功能的代碼可以看出文件內數據的存儲順序。在圖 7-2的窗口上編輯表格的數據后,單擊工具欄上的“保存 st 文件”,可以使用 Qt 預定義編碼方式保存文件。此按鈕的響應代碼如下:

void MainWindow::on_actSave_triggered()
{ //以Qt預定義編碼保存數據文件
    QString curPath=QDir::currentPath();
    QString aFileName=QFileDialog::getSaveFileName(this,tr("選擇保存文件"),curPath,
                 "Qt預定義編碼數據文件(*.stm)");

    if (aFileName.isEmpty())
        return; //

   if  (saveDataAsStream(aFileName)) //保存為流數據文件
       QMessageBox::information(this,"提示消息","文件已經成功保存!");
}

bool MainWindow::saveDataAsStream(QString &aFileName)
{//將模型數據保存為Qt預定義編碼的數據文件
    QFile aFile(aFileName);  //以文件方式讀出
    if (!(aFile.open(QIODevice::WriteOnly | QIODevice::Truncate)))
        return false;

    QDataStream aStream(&aFile);
    aStream.setVersion(QDataStream::Qt_5_9); //設置版本號,寫入和讀取的版本號要兼容

    qint16  rowCount=theModel->rowCount(); //數據模型行數
    qint16  colCount=theModel->columnCount(); //數據模型列數

    aStream<<rowCount; //寫入文件流,行數
    aStream<<colCount;//寫入文件流,列數

//獲取表頭文字
    for (int i=0;i<theModel->columnCount();i++)
    {
        QString str=theModel->horizontalHeaderItem(i)->text();//獲取表頭文字
        aStream<<str; //字符串寫入文件流,Qt預定義編碼方式
    }


//獲取數據區(qū)的數據
    for (int i=0;i<theModel->rowCount();i++)
    {
        QStandardItem* aItem=theModel->item(i,0); //測深
        qint16 ceShen=aItem->data(Qt::DisplayRole).toInt();
        aStream<<ceShen;// 寫入文件流,qint16

        aItem=theModel->item(i,1); //垂深
        qreal chuiShen=aItem->data(Qt::DisplayRole).toFloat();
        aStream<<chuiShen;//寫入文件流, qreal

        aItem=theModel->item(i,2); //方位
        qreal fangWei=aItem->data(Qt::DisplayRole).toFloat();
        aStream<<fangWei;//寫入文件流, qreal

        aItem=theModel->item(i,3); //位移
        qreal weiYi=aItem->data(Qt::DisplayRole).toFloat();
        aStream<<weiYi;//寫入文件流, qreal

        aItem=theModel->item(i,4); //固井質量
        QString zhiLiang=aItem->data(Qt::DisplayRole).toString();
        aStream<<zhiLiang;// 寫入文件流,字符串

        aItem=theModel->item(i,5); //測井
        bool quYang=(aItem->checkState()==Qt::Checked);
        aStream<<quYang;// 寫入文件流,bool型
    }
    aFile.close();
    return true;
}

自定義函數 saveDataAsStream()將表格的數據模型 theModel 的數據保存為一個 stm 文件。代碼首先是創(chuàng)建 QFile 對象aFile 打開文件,然后創(chuàng)建 DataStream 對象aStream 與 QFile 對象關聯。

在開始寫數據流之前,為QDataStream 對象 aStream 設置版本號,即調用 setVersion()函數并傳遞一個QDataStream::Version 枚舉類型的值。

aStream.setVersion(QDataStream::Qt_5_9); //設置版本號,寫入和讀取的版本號要兼容

這表示aStream將以QDataStream::Qt_5_9版本的預定義類型寫文件流

注意:以 Qt 的預定義類型編碼保存的文件需要指定流版本號,因為每個版本的 Qt 對數據類型的編碼可能有差別,需要保證寫文件和讀文件的流版本是兼容的。

接下來,就是按照需要保存數據的順序寫入文件流。例如在文件開始,先寫入行數和列數兩個 qint16 的整數。因為行數和列數關系到后面的數據是如何組織的,因此在讀取文件數據時,首先讀取這兩個整數,然后根據數據存儲方式的約定,就知道后續(xù)數據該如何讀取了。向文件寫入數據時,直接用流的輸入操作,如:

    aStream>>rowCount; //讀取行數
    aStream>>colCount; //列數

在讀取各列的表頭字符串之后,將其寫入數據流。然后逐行掃描表格的數據模型,將每一行的列數據寫入數據流。
數據流寫入數據時都使用運算符“<<”,不論寫的是 qint16、qreal,還是字符串。除了可以寫入基本的數據類型外,QDataStream 流操作還可以寫入很多其他類型的數據,如QBrush、QColor、QImage、QIcon 等,這些稱為可序列化的數據類型(Serializing Qt Data Types)
QDataStream 以流操作寫入這些數據時,我們并不知道文件里每個字節(jié)是如何存儲的,但是知道數據寫入的順序,以及每次寫入數據的類型。在文件數據讀出時,只需按照順序和類型對應讀出即可。

2.2 stm文件格式

根據 saveDataAsStream()函數的代碼,可知 Qt 預定義編碼保存的 stm 文件的格式,如表 7-1所示。

07-2_Qt 5.9 C++開發(fā)指南_二進制文件讀寫(stm和dat格式),# Qt 5.9 C++開發(fā)指南,qt,c++
07-2_Qt 5.9 C++開發(fā)指南_二進制文件讀寫(stm和dat格式),# Qt 5.9 C++開發(fā)指南,qt,c++

從表 7-1 中可以知道 stm 文件的數據存儲順序和類型,但是并不知道 qit16 類型的數據存儲為幾個字節(jié)以及 QString 類型的數據是如何定義長度和字符內容的,其實也不需要知道這些具體的存儲方式,在從文件讀出時,只需按照表 7-1 的順序和類型讀出數據即可。

2.3 讀取stm文件

下面是工具欄按鈕“打開 stm 文件”的響應代碼及相關函數代碼,選擇需要打開的 stm 文件后,主要是調用自定義函數 openDataAsStream()將其打開。

void MainWindow::on_actOpen_triggered()
{
    QString curPath=QDir::currentPath();
//調用打開文件對話框打開一個文件
    QString aFileName=QFileDialog::getOpenFileName(this,tr("打開一個文件"),curPath,
                 "流數據文件(*.stm)");

    if (aFileName.isEmpty())
        return; //

    if  (openDataAsStream(aFileName)) //保存為流數據文件
         QMessageBox::information(this,"提示消息","文件已經打開!");
}

bool MainWindow::openDataAsStream(QString &aFileName)
{ //從Qt預定義流文件讀入數據
    QFile aFile(aFileName);  //以文件方式讀出
    if (!(aFile.open(QIODevice::ReadOnly)))
        return false;

    QDataStream aStream(&aFile); //用文本流讀取文件
    aStream.setVersion(QDataStream::Qt_5_9); //設置流文件版本號

    qint16  rowCount,colCount;
    aStream>>rowCount; //讀取行數
    aStream>>colCount; //列數

    this->resetTable(rowCount); //表格復位

    //獲取表頭文字
    QString str;
    for (int i=0;i<colCount;i++)
        aStream>>str;  //讀取表頭字符串

    //獲取數據區(qū)文字,
    qint16  ceShen;
    qreal  chuiShen;
    qreal  fangWei;
    qreal  weiYi;
    QString  zhiLiang;
    bool    quYang;
    QStandardItem   *aItem;
    QModelIndex index;

    for (int i=0;i<rowCount;i++)
    {
        aStream>>ceShen;//讀取測深, qint16
        index=theModel->index(i,0);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(ceShen,Qt::DisplayRole);

        aStream>>chuiShen;//垂深,qreal
        index=theModel->index(i,1);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(chuiShen,Qt::DisplayRole);


        aStream>>fangWei;//方位,qreal
        index=theModel->index(i,2);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(fangWei,Qt::DisplayRole);


        aStream>>weiYi;//位移,qreal
        index=theModel->index(i,3);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(weiYi,Qt::DisplayRole);


        aStream>>zhiLiang;//固井質量,QString
        index=theModel->index(i,4);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(zhiLiang,Qt::DisplayRole);

        aStream>>quYang;//bool
        index=theModel->index(i,5);
        aItem=theModel->itemFromIndex(index);
        if (quYang)
            aItem->setCheckState(Qt::Checked);
        else
            aItem->setCheckState(Qt::Unchecked);
    }

    aFile.close();
    return true;
}

讀取 stm 文件的數據之前也必須設置 QDataStream 的流版本號,應該等于或高于數據保存時的流版本號。

然后就是按照表 7-1 所示的寫入數據時的順序和類型,相應地讀出每個數據。文件里最早的兩個數據是表格的行數和列數,讀出這兩個數據,就能知道數據的行數和列數,并調用自定義函數 resetTable()給數據模型復位,并設置其行數。
然后將保存的每行數據讀入到數據模型的每個項中,這樣窗口上的 QTableView 組件就可以顯示數據了。

使用QDataStream 的流操作方式讀寫文件的特點如下。

  • 讀寫操作都比較方便,支持讀寫各種數據類型,包括 Qt 的一些類,還可以為流數據讀寫擴展自定義的數據類型。讀寫某種類型的數據時,只要是流支持即可,而在文件內部是如何存儲的,用戶無需關心,由 Qt 預定義。

  • 寫文件和讀文件時必須保證使用的流版本兼容,即流的版本號相同,或讀取文件的流版本號高于寫文件時的流版本號。這是因為在不同的流版本中,流支持的數據類型的讀寫方式可能有所改變,必須保證讀寫版本的兼容。

  • 用這種方式保存文件時,寫入數據采用 Qt 預定義的編碼,即寫入文件的二進制編碼是由Qt預定義的,寫多少個字節(jié)、字節(jié)是什么樣的順序,用戶是不知道的。如果是由QDataStream讀取數據,只需按類型讀出即可。但是,如果由這種方法創(chuàng)建的文件是用于交換的,需要用其他的編程語言(如 Matlab) 來讀取文件內容,則存在問題了。因為其他語言并沒有與Qt 的流寫入完全一致的流讀出功能,例如,其他語言并不知道 Qt 保存的 QString 或 QFont的內容是如何組織的。

3. 標準編碼文件的讀寫

3.1 保存為dat文件

前面是采用 Qt 預定義編碼讀寫 stm 文件,這種方法使用簡單,但是文件的格式不完全透明,不能創(chuàng)建用于交換的通用格式文件。
創(chuàng)建通用格式文件(即文件格式完全透明,每個字節(jié)都有具體的定義,如 SEG-Y 文件)的方法是以標準編碼方式創(chuàng)建文件,使文件的每個字節(jié)都有具體的定義。用戶在讀取這種文件時,按照文件格式定義讀取出每個字節(jié)數據并做解析即可,不管使用什么編程語言都可以編寫讀寫文件的程序。
主窗口工具欄上的“保存 dat 文件”按將表格中的數據保存為標準編碼的文件,文件后綴是“.dat”。保存 dat 文件的代碼是:

void MainWindow::on_actSaveBin_triggered()
{//保存二進制文件
    QString curPath=QDir::currentPath();
    //調用打開文件對話框選擇一個文件
    QString aFileName=QFileDialog::getSaveFileName(this,tr("選擇保存文件"),curPath,
                                                   "二進制數據文件(*.dat)");
    if (aFileName.isEmpty())
        return; //

    if  (saveBinaryFile(aFileName)) //保存為流數據文件
        QMessageBox::information(this,"提示消息","文件已經成功保存!");
}

bool MainWindow::saveBinaryFile(QString &aFileName)
{ //保存為純二進制文件
    QFile aFile(aFileName);  //以文件方式讀出
    if (!(aFile.open(QIODevice::WriteOnly)))
        return false;

    QDataStream aStream(&aFile); //用文本流讀取文件
//    aStream.setVersion(QDataStream::Qt_5_9); //無需設置數據流的版本
    aStream.setByteOrder(QDataStream::LittleEndian);//windows平臺
//    aStream.setByteOrder(QDataStream::BigEndian);//QDataStream::LittleEndian

    qint16  rowCount=theModel->rowCount();
    qint16  colCount=theModel->columnCount();

    aStream.writeRawData((char *)&rowCount,sizeof(qint16)); //寫入文件流
    aStream.writeRawData((char *)&colCount,sizeof(qint16));//寫入文件流


//獲取表頭文字
    QByteArray  btArray;
    QStandardItem   *aItem;
    for (int i=0;i<theModel->columnCount();i++)
    {
        aItem=theModel->horizontalHeaderItem(i); //獲取表頭item
        QString str=aItem->text(); //獲取表頭文字
        btArray=str.toUtf8(); //轉換為字符數組
        aStream.writeBytes(btArray,btArray.length()); //寫入文件流,長度uint型,然后是字符串內容
    }

//獲取數據區(qū)文字,
    qint8   yes=1,no=0; //分別代表邏輯值 true和false
    for (int i=0;i<theModel->rowCount();i++)
    {
        aItem=theModel->item(i,0); //測深
        qint16 ceShen=aItem->data(Qt::DisplayRole).toInt();//qint16類型
        aStream.writeRawData((char *)&ceShen,sizeof(qint16));//寫入文件流

        aItem=theModel->item(i,1); //垂深
        qreal chuiShen=aItem->data(Qt::DisplayRole).toFloat();//qreal 類型
        aStream.writeRawData((char *)&chuiShen,sizeof(qreal));//寫入文件流

        aItem=theModel->item(i,2); //方位
        qreal fangWei=aItem->data(Qt::DisplayRole).toFloat();
        aStream.writeRawData((char *)&fangWei,sizeof(qreal));

        aItem=theModel->item(i,3); //位移
        qreal weiYi=aItem->data(Qt::DisplayRole).toFloat();
        aStream.writeRawData((char *)&weiYi,sizeof(qreal));

        aItem=theModel->item(i,4); //固井質量
        QString zhiLiang=aItem->data(Qt::DisplayRole).toString();
        btArray=zhiLiang.toUtf8();
        aStream.writeBytes(btArray,btArray.length()); //寫入長度,uint,然后是字符串
//        aStream.writeRawData(btArray,btArray.length());//對于字符串,應使用writeBytes()函數

        aItem=theModel->item(i,5); //測井取樣
        bool quYang=(aItem->checkState()==Qt::Checked); //true or false
        if (quYang)
            aStream.writeRawData((char *)&yes,sizeof(qint8));
        else
            aStream.writeRawData((char *)&no,sizeof(qint8));
    }

    aFile.close();
    return true;
}
  • 字節(jié)序

在保存為標準編碼的二進制文件時,無須指定 QDataStream 的版本,因為不會用到 Qt的類型預定義編碼,文件的每個字節(jié)的意義都是用戶自己定義的。但是如有必要,需要為文件指定字節(jié)順序,如:

aStream.setByteOrder(QDataStream::LittleEndian);//windows平臺

字節(jié)順序分為大端字節(jié)序和小端字節(jié)序,小端字節(jié)序指低字節(jié)數據存放在內存低地址處,高字節(jié)數據存放在內存高地址處;大端字節(jié)序則相反。

基于X86平臺的計算機是小端字節(jié)序的,所以 Windows 系統是小端字節(jié)序,而有的嵌入式平臺或工作站平臺則是大端字節(jié)序的。讀取一個文件時,首先需要知道它是以什么字節(jié)序存儲的這樣才可以正確的讀出。

setByteOrder()函數的參數是 QDataStream::ByteOrder 枚舉類型常量,QDataStream::BigEndian
是大端字節(jié)序,QDataStream::LittleEndian 是小端字節(jié)序。

  • writeRawData()函數

QdataStream 采用函數 writeRawData()將數據寫入數據流,在保存qint8、qint16、qreal等類型的數據時都使用這個函數,其函數原型是:

int QDataStream::writeRawData(const char *s, int len)

其中參數s是一個指向字節(jié)型數據的指針,len 是字節(jié)數據的長度。調用 writeRawData()函數將會向文件流連續(xù)寫入len 個字節(jié)的數據,這些字節(jié)數據保存在指針 s 指向的起始地址里。例如,將qint16類型變量rowCount 寫入文件的語句是:

    qint16  rowCount=theModel->rowCount();
    qint16  colCount=theModel->columnCount();
  • writeBytes()函數

在將字符串數據寫入文件時,使用的是 writeBytes()函數,而不是 writeRawData()。下面是writeBytes()函數的原型定義:

QDataStream &QDataStream::writeBytes(const char *s, uint len)

其中參數s 是一個指向字節(jié)型數據的指針,len 是字節(jié)數據的長度。writeBytes()在寫入數據時,會先將 len 作為一個 quint32 類型寫入數據流,然后再寫入 len 個從指針s 獲取的數據。

writeBytes()適合于寫入字符串數據,因為在寫入字符串之前要先寫入字符串的長度,這樣在讀取文件時,就能知道字符串的長度,以便正確讀出字符串。

例如,下面的代碼將字符串“Depth”寫入文件流:

QString str="Depth”;
QByteArray btArray=str.toUtf8();
aStream.writeBytes(btArray,btArray.length());

文件中實際保存的內容見表 7-2。前 4 個字節(jié)是 quint32 類型的整數,表示保存數據的字節(jié)個數,這里是 5,表示后續(xù)有5 個字節(jié)數據。從第 5 字節(jié)開始,是保存的字符串”Depth”的每個字符的ASCII碼。
07-2_Qt 5.9 C++開發(fā)指南_二進制文件讀寫(stm和dat格式),# Qt 5.9 C++開發(fā)指南,qt,c++
由于寫入文件的字符串的長度一般是不固定的,因此如果以 writeRawData()函數寫入文件,只會寫入字符串的內容,而沒有表示字符串的長度。在文件讀出時,如果不已知字符串長度,則難以正確讀出字符串內容。而 writeBytes()函數首先寫入了字符串的長度,在讀取文件時,先從前四個字節(jié)讀出字符串長度,知道數據有多少個字節(jié)就可以正確讀出了。

QDataStream 提供了與 writeBytes()對應的函數 readBytes(),它可以自動讀取長度和內容,適用于字符串數據的讀取。

3.2 dat文件格式

用 saveBinaryFile()函數保存數據為標準編碼二進制文件,文件后綴為“.dat”。根據saveBinaryFile()函數的內容,dat 文件的格式見表 7-3。

07-2_Qt 5.9 C++開發(fā)指南_二進制文件讀寫(stm和dat格式),# Qt 5.9 C++開發(fā)指南,qt,c++

在表 7-3 中,可以看到文件內的每個字節(jié)都是有具體定義的,這樣,無論用什么語言編寫一個文件讀取的程序,只要按照這個格式來讀取,都可以正確讀出文件內容。

dat 文件的數據是否是按照表 7-3 所示的順序存儲的呢?可以創(chuàng)建一個簡單的數據表格,保存為 dat 后綴的文件,然后用顯示文件二進制內容的軟件來查看,如 ltraEdit 或 WinHex,這些軟件在分析文件格式,編寫文件讀寫程序時特別有用。

3.3 讀取dat文件

對于保存的 dat 文件,主窗口工具欄上的“打開 dat 文件”按鈕可以打開保存的 dat 文件,下面是打開 dat 文件的函數 openBinaryFile()的代碼。

bool MainWindow::openBinaryFile(QString &aFileName)
{//打開二進制文件
    QFile aFile(aFileName);  //以文件方式讀出
    if (!(aFile.open(QIODevice::ReadOnly)))
        return false;

    QDataStream aStream(&aFile); //用文本流讀取文件
//    aStream.setVersion(QDataStream::Qt_5_9); //設置數據流的版本
    aStream.setByteOrder(QDataStream::LittleEndian);
//    aStream.setByteOrder(QDataStream::BigEndian);

    qint16  rowCount,colCount;
    aStream.readRawData((char *)&rowCount, sizeof(qint16));
    aStream.readRawData((char *)&colCount, sizeof(qint16));

    this->resetTable(rowCount);


    //獲取表頭文字,但是并不利用
    char *buf;
    uint strLen;  //也就是 quint32
    for (int i=0;i<colCount;i++)
    {
        aStream.readBytes(buf,strLen);//同時讀取字符串長度,和字符串內容
        QString str=QString::fromLocal8Bit(buf,strLen); //可處理漢字
    }

//獲取數據區(qū)數據
    QStandardItem   *aItem;

    qint16  ceShen;
    qreal  chuiShen;
    qreal  fangWei;
    qreal  weiYi;
    QString  zhiLiang;
    qint8   quYang; //分別代表邏輯值 true和false
    QModelIndex index;

    for (int i=0;i<rowCount;i++)
    {
        aStream.readRawData((char *)&ceShen, sizeof(qint16)); //測深
        index=theModel->index(i,0);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(ceShen,Qt::DisplayRole);

        aStream.readRawData((char *)&chuiShen, sizeof(qreal)); //垂深
        index=theModel->index(i,1);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(chuiShen,Qt::DisplayRole);

        aStream.readRawData((char *)&fangWei, sizeof(qreal)); //方位
        index=theModel->index(i,2);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(fangWei,Qt::DisplayRole);

        aStream.readRawData((char *)&weiYi, sizeof(qreal)); //位移
        index=theModel->index(i,3);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(weiYi,Qt::DisplayRole);

        aStream.readBytes(buf,strLen);//固井質量
        zhiLiang=QString::fromLocal8Bit(buf,strLen);
        index=theModel->index(i,4);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(zhiLiang,Qt::DisplayRole);

        aStream.readRawData((char *)&quYang, sizeof(qint8)); //測井取樣
        index=theModel->index(i,5);
        aItem=theModel->itemFromIndex(index);
        if (quYang==1)
            aItem->setCheckState(Qt::Checked);
        else
            aItem->setCheckState(Qt::Unchecked);
    }

    aFile.close();
    return true;
}
  • 字節(jié)序

在流創(chuàng)建后,需要用 setByteOrder()函數指定字節(jié)序,并且與寫入文件時用的字節(jié)序一致。

  • readRawData()函數

在讀取基本類型數據時,使用QDataStream 的readRawData()函數,該函數原型為:

int QDataStream::readRawData(char *s, int len)

它會讀取 len 個字節(jié)的數據,并且保存到指針 s 指向的存儲區(qū)。例如:

    qint16  rowCount,colCount;
    aStream.readRawData((char *)&rowCount, sizeof(qint16));
    aStream.readRawData((char *)&colCount, sizeof(qint16));
  • readBytes()函數

讀取字符串時使用readBytes()函數,它是與writeBytes()功能對應的函數,其函數原型為:

QDataStream &QDataStream::readBytes(char *&s, uint &l)

對應表格 7-2,使用readBytes()函數時,會先自動讀取前 4 個字節(jié)數據作為quint32 的數據并賦值給 len 參數,因為 len 是以引用方式傳遞的參數,所以,len 返回讀取的數據的字節(jié)數。然后根據 len 的大小讀取相應字節(jié)的數據,存儲到指針 s 指向的存儲區(qū)。

4. 框架及源碼

4.1 可視化UI設計

07-2_Qt 5.9 C++開發(fā)指南_二進制文件讀寫(stm和dat格式),# Qt 5.9 C++開發(fā)指南,qt,c++文章來源地址http://www.zghlxwxcb.cn/news/detail-639233.html

4.2 mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include    <QFileDialog>
#include    <QDataStream>
#include    <QMessageBox>

void MainWindow::resetTable(int aRowCount)
{ //表格復位,先刪除所有行,再設置新的行數,表頭不變
//    QStringList     headerList;
//    headerList<<"測深(m)"<<"垂深(m)"<<"方位(°)"<<"總位移(m)"<<"固井質量"<<"測井取樣";
//    theModel->setHorizontalHeaderLabels(headerList); //設置表頭文字

    theModel->removeRows(0,theModel->rowCount()); //刪除所有行
    theModel->setRowCount(aRowCount);//設置新的行數

    QString str=theModel->headerData(theModel->columnCount()-1,
                     Qt::Horizontal,Qt::DisplayRole).toString();

    for (int i=0;i<theModel->rowCount();i++)
    { //設置最后一列
        QModelIndex index=theModel->index(i,FixedColumnCount-1); //獲取模型索引
        QStandardItem* aItem=theModel->itemFromIndex(index); //獲取item
        aItem->setCheckable(true);
        aItem->setData(str,Qt::DisplayRole);
        aItem->setEditable(false); //不可編輯
    }
}

bool MainWindow::saveDataAsStream(QString &aFileName)
{//將模型數據保存為Qt預定義編碼的數據文件
    QFile aFile(aFileName);  //以文件方式讀出
    if (!(aFile.open(QIODevice::WriteOnly | QIODevice::Truncate)))
        return false;

    QDataStream aStream(&aFile);
    aStream.setVersion(QDataStream::Qt_5_9); //設置版本號,寫入和讀取的版本號要兼容

    qint16  rowCount=theModel->rowCount(); //數據模型行數
    qint16  colCount=theModel->columnCount(); //數據模型列數

    aStream<<rowCount; //寫入文件流,行數
    aStream<<colCount;//寫入文件流,列數

//獲取表頭文字
    for (int i=0;i<theModel->columnCount();i++)
    {
        QString str=theModel->horizontalHeaderItem(i)->text();//獲取表頭文字
        aStream<<str; //字符串寫入文件流,Qt預定義編碼方式
    }


//獲取數據區(qū)的數據
    for (int i=0;i<theModel->rowCount();i++)
    {
        QStandardItem* aItem=theModel->item(i,0); //測深
        qint16 ceShen=aItem->data(Qt::DisplayRole).toInt();
        aStream<<ceShen;// 寫入文件流,qint16

        aItem=theModel->item(i,1); //垂深
        qreal chuiShen=aItem->data(Qt::DisplayRole).toFloat();
        aStream<<chuiShen;//寫入文件流, qreal

        aItem=theModel->item(i,2); //方位
        qreal fangWei=aItem->data(Qt::DisplayRole).toFloat();
        aStream<<fangWei;//寫入文件流, qreal

        aItem=theModel->item(i,3); //位移
        qreal weiYi=aItem->data(Qt::DisplayRole).toFloat();
        aStream<<weiYi;//寫入文件流, qreal

        aItem=theModel->item(i,4); //固井質量
        QString zhiLiang=aItem->data(Qt::DisplayRole).toString();
        aStream<<zhiLiang;// 寫入文件流,字符串

        aItem=theModel->item(i,5); //測井
        bool quYang=(aItem->checkState()==Qt::Checked);
        aStream<<quYang;// 寫入文件流,bool型
    }
    aFile.close();
    return true;
}

bool MainWindow::openDataAsStream(QString &aFileName)
{ //從Qt預定義流文件讀入數據
    QFile aFile(aFileName);  //以文件方式讀出
    if (!(aFile.open(QIODevice::ReadOnly)))
        return false;

    QDataStream aStream(&aFile); //用文本流讀取文件
    aStream.setVersion(QDataStream::Qt_5_9); //設置流文件版本號

    qint16  rowCount,colCount;
    aStream>>rowCount; //讀取行數
    aStream>>colCount; //列數

    this->resetTable(rowCount); //表格復位

    //獲取表頭文字
    QString str;
    for (int i=0;i<colCount;i++)
        aStream>>str;  //讀取表頭字符串

    //獲取數據區(qū)文字,
    qint16  ceShen;
    qreal  chuiShen;
    qreal  fangWei;
    qreal  weiYi;
    QString  zhiLiang;
    bool    quYang;
    QStandardItem   *aItem;
    QModelIndex index;

    for (int i=0;i<rowCount;i++)
    {
        aStream>>ceShen;//讀取測深, qint16
        index=theModel->index(i,0);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(ceShen,Qt::DisplayRole);

        aStream>>chuiShen;//垂深,qreal
        index=theModel->index(i,1);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(chuiShen,Qt::DisplayRole);


        aStream>>fangWei;//方位,qreal
        index=theModel->index(i,2);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(fangWei,Qt::DisplayRole);


        aStream>>weiYi;//位移,qreal
        index=theModel->index(i,3);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(weiYi,Qt::DisplayRole);


        aStream>>zhiLiang;//固井質量,QString
        index=theModel->index(i,4);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(zhiLiang,Qt::DisplayRole);

        aStream>>quYang;//bool
        index=theModel->index(i,5);
        aItem=theModel->itemFromIndex(index);
        if (quYang)
            aItem->setCheckState(Qt::Checked);
        else
            aItem->setCheckState(Qt::Unchecked);
    }

    aFile.close();
    return true;
}

bool MainWindow::saveBinaryFile(QString &aFileName)
{ //保存為純二進制文件
    QFile aFile(aFileName);  //以文件方式讀出
    if (!(aFile.open(QIODevice::WriteOnly)))
        return false;

    QDataStream aStream(&aFile); //用文本流讀取文件
//    aStream.setVersion(QDataStream::Qt_5_9); //無需設置數據流的版本
    aStream.setByteOrder(QDataStream::LittleEndian);//windows平臺
//    aStream.setByteOrder(QDataStream::BigEndian);//QDataStream::LittleEndian

    qint16  rowCount=theModel->rowCount();
    qint16  colCount=theModel->columnCount();

    aStream.writeRawData((char *)&rowCount,sizeof(qint16)); //寫入文件流
    aStream.writeRawData((char *)&colCount,sizeof(qint16));//寫入文件流


//獲取表頭文字
    QByteArray  btArray;
    QStandardItem   *aItem;
    for (int i=0;i<theModel->columnCount();i++)
    {
        aItem=theModel->horizontalHeaderItem(i); //獲取表頭item
        QString str=aItem->text(); //獲取表頭文字
        btArray=str.toUtf8(); //轉換為字符數組
        aStream.writeBytes(btArray,btArray.length()); //寫入文件流,長度uint型,然后是字符串內容
    }

//獲取數據區(qū)文字,
    qint8   yes=1,no=0; //分別代表邏輯值 true和false
    for (int i=0;i<theModel->rowCount();i++)
    {
        aItem=theModel->item(i,0); //測深
        qint16 ceShen=aItem->data(Qt::DisplayRole).toInt();//qint16類型
        aStream.writeRawData((char *)&ceShen,sizeof(qint16));//寫入文件流

        aItem=theModel->item(i,1); //垂深
        qreal chuiShen=aItem->data(Qt::DisplayRole).toFloat();//qreal 類型
        aStream.writeRawData((char *)&chuiShen,sizeof(qreal));//寫入文件流

        aItem=theModel->item(i,2); //方位
        qreal fangWei=aItem->data(Qt::DisplayRole).toFloat();
        aStream.writeRawData((char *)&fangWei,sizeof(qreal));

        aItem=theModel->item(i,3); //位移
        qreal weiYi=aItem->data(Qt::DisplayRole).toFloat();
        aStream.writeRawData((char *)&weiYi,sizeof(qreal));

        aItem=theModel->item(i,4); //固井質量
        QString zhiLiang=aItem->data(Qt::DisplayRole).toString();
        btArray=zhiLiang.toUtf8();
        aStream.writeBytes(btArray,btArray.length()); //寫入長度,uint,然后是字符串
//        aStream.writeRawData(btArray,btArray.length());//對于字符串,應使用writeBytes()函數

        aItem=theModel->item(i,5); //測井取樣
        bool quYang=(aItem->checkState()==Qt::Checked); //true or false
        if (quYang)
            aStream.writeRawData((char *)&yes,sizeof(qint8));
        else
            aStream.writeRawData((char *)&no,sizeof(qint8));
    }

    aFile.close();
    return true;
}

bool MainWindow::openBinaryFile(QString &aFileName)
{//打開二進制文件
    QFile aFile(aFileName);  //以文件方式讀出
    if (!(aFile.open(QIODevice::ReadOnly)))
        return false;

    QDataStream aStream(&aFile); //用文本流讀取文件
//    aStream.setVersion(QDataStream::Qt_5_9); //設置數據流的版本
    aStream.setByteOrder(QDataStream::LittleEndian);
//    aStream.setByteOrder(QDataStream::BigEndian);

    qint16  rowCount,colCount;
    aStream.readRawData((char *)&rowCount, sizeof(qint16));
    aStream.readRawData((char *)&colCount, sizeof(qint16));

    this->resetTable(rowCount);


    //獲取表頭文字,但是并不利用
    char *buf;
    uint strLen;  //也就是 quint32
    for (int i=0;i<colCount;i++)
    {
        aStream.readBytes(buf,strLen);//同時讀取字符串長度,和字符串內容
        QString str=QString::fromLocal8Bit(buf,strLen); //可處理漢字
    }

//獲取數據區(qū)數據
    QStandardItem   *aItem;

    qint16  ceShen;
    qreal  chuiShen;
    qreal  fangWei;
    qreal  weiYi;
    QString  zhiLiang;
    qint8   quYang; //分別代表邏輯值 true和false
    QModelIndex index;

    for (int i=0;i<rowCount;i++)
    {
        aStream.readRawData((char *)&ceShen, sizeof(qint16)); //測深
        index=theModel->index(i,0);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(ceShen,Qt::DisplayRole);

        aStream.readRawData((char *)&chuiShen, sizeof(qreal)); //垂深
        index=theModel->index(i,1);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(chuiShen,Qt::DisplayRole);

        aStream.readRawData((char *)&fangWei, sizeof(qreal)); //方位
        index=theModel->index(i,2);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(fangWei,Qt::DisplayRole);

        aStream.readRawData((char *)&weiYi, sizeof(qreal)); //位移
        index=theModel->index(i,3);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(weiYi,Qt::DisplayRole);

        aStream.readBytes(buf,strLen);//固井質量
        zhiLiang=QString::fromLocal8Bit(buf,strLen);
        index=theModel->index(i,4);
        aItem=theModel->itemFromIndex(index);
        aItem->setData(zhiLiang,Qt::DisplayRole);

        aStream.readRawData((char *)&quYang, sizeof(qint8)); //測井取樣
        index=theModel->index(i,5);
        aItem=theModel->itemFromIndex(index);
        if (quYang==1)
            aItem->setCheckState(Qt::Checked);
        else
            aItem->setCheckState(Qt::Unchecked);
    }

    aFile.close();
    return true;
}


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    theModel = new QStandardItemModel(5,FixedColumnCount,this); //創(chuàng)建數據模型
    QStringList     headerList;
    headerList<<"Depth"<<"Measured Depth"<<"Direction"<<"Offset"<<"Quality"<<"Sampled";
    theModel->setHorizontalHeaderLabels(headerList); //設置表頭文字


    theSelection = new QItemSelectionModel(theModel);//Item選擇模型
    connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),
            this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));

    //為tableView設置數據模型
    ui->tableView->setModel(theModel); //設置數據模型
    ui->tableView->setSelectionModel(theSelection);//設置選擇模型

//為各列設置自定義代理組件
    ui->tableView->setItemDelegateForColumn(0,&intSpinDelegate);  //測深,整數
    ui->tableView->setItemDelegateForColumn(1,&floatSpinDelegate);  //浮點數
    ui->tableView->setItemDelegateForColumn(2,&floatSpinDelegate); //浮點數
    ui->tableView->setItemDelegateForColumn(3,&floatSpinDelegate); //浮點數
    ui->tableView->setItemDelegateForColumn(4,&comboBoxDelegate); //Combbox選擇型


    resetTable(5); //表格復位

    setCentralWidget(ui->tabWidget); //

//創(chuàng)建狀態(tài)欄組件
    LabCellPos = new QLabel("當前單元格:",this);
    LabCellPos->setMinimumWidth(180);
    LabCellPos->setAlignment(Qt::AlignHCenter);

    LabCellText = new QLabel("單元格內容:",this);
    LabCellText->setMinimumWidth(200);

    ui->statusBar->addWidget(LabCellPos);
    ui->statusBar->addWidget(LabCellText);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
    Q_UNUSED(previous);
    if (current.isValid())
    {
        LabCellPos->setText(QString::asprintf("當前單元格:%d行,%d列",
                                  current.row(),current.column()));
        QStandardItem   *aItem;
        aItem=theModel->itemFromIndex(current); //從模型索引獲得Item
        this->LabCellText->setText("單元格內容:"+aItem->text());

        QFont   font=aItem->font();
        ui->actFontBold->setChecked(font.bold());
    }
}

void MainWindow::on_actOpen_triggered()
{
    QString curPath=QDir::currentPath();
//調用打開文件對話框打開一個文件
    QString aFileName=QFileDialog::getOpenFileName(this,tr("打開一個文件"),curPath,
                 "流數據文件(*.stm)");

    if (aFileName.isEmpty())
        return; //

    if  (openDataAsStream(aFileName)) //保存為流數據文件
         QMessageBox::information(this,"提示消息","文件已經打開!");
}

void MainWindow::on_actAppend_triggered()
{ //添加行
    QList<QStandardItem*>    aItemList; //容器類
    QStandardItem   *aItem;
    QString str;
    for(int i=0;i<FixedColumnCount-2;i++)
    {
        aItem=new QStandardItem("0"); //創(chuàng)建Item
        aItemList<<aItem;   //添加到容器
    }
    aItem=new QStandardItem("優(yōu)"); //創(chuàng)建Item
    aItemList<<aItem;   //添加到容器

    str=theModel->headerData(theModel->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();
    aItem=new QStandardItem(str); //創(chuàng)建Item
    aItem->setCheckable(true);
    aItem->setEditable(false);
    aItemList<<aItem;   //添加到容器

    theModel->insertRow(theModel->rowCount(),aItemList); //插入一行,需要每個Cell的Item
    QModelIndex curIndex=theModel->index(theModel->rowCount()-1,0);//創(chuàng)建最后一行的ModelIndex
    theSelection->clearSelection();
    theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
}

void MainWindow::on_actInsert_triggered()
{//插入行
    QList<QStandardItem*>    aItemList;  //QStandardItem的容器類
    QStandardItem   *aItem;
    QString str;
    for(int i=0;i<FixedColumnCount-2;i++)
    {
        aItem=new QStandardItem("0"); //新建一個QStandardItem
        aItemList<<aItem;//添加到容器類
    }
    aItem=new QStandardItem("優(yōu)"); //新建一個QStandardItem
    aItemList<<aItem;//添加到容器類

    str=theModel->headerData(theModel->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();
    aItem=new QStandardItem(str); //創(chuàng)建Item
    aItem->setCheckable(true);
    aItem->setEditable(false);
    aItemList<<aItem;//添加到容器類
    QModelIndex curIndex=theSelection->currentIndex();
    theModel->insertRow(curIndex.row(),aItemList);
    theSelection->clearSelection();
    theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
}

void MainWindow::on_actDelete_triggered()
{ //刪除行
    QModelIndex curIndex=theSelection->currentIndex();
    if (curIndex.row()==theModel->rowCount()-1)//(curIndex.isValid())
        theModel->removeRow(curIndex.row());
    else
    {
        theModel->removeRow(curIndex.row());
        theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
    }
}


void MainWindow::on_actSave_triggered()
{ //以Qt預定義編碼保存數據文件
    QString curPath=QDir::currentPath();
    QString aFileName=QFileDialog::getSaveFileName(this,tr("選擇保存文件"),curPath,
                 "Qt預定義編碼數據文件(*.stm)");

    if (aFileName.isEmpty())
        return; //

   if  (saveDataAsStream(aFileName)) //保存為流數據文件
       QMessageBox::information(this,"提示消息","文件已經成功保存!");
}

void MainWindow::on_actAlignCenter_triggered()
{
    if (!theSelection->hasSelection())
        return;

    QModelIndexList selectedIndix=theSelection->selectedIndexes();

    QModelIndex aIndex;
    QStandardItem   *aItem;

    for (int i=0;i<selectedIndix.count();i++)
    {
        aIndex=selectedIndix.at(i);
        aItem=theModel->itemFromIndex(aIndex);
        aItem->setTextAlignment(Qt::AlignHCenter);
    }
}

void MainWindow::on_actFontBold_triggered(bool checked)
{
    if (!theSelection->hasSelection())
        return;

    QModelIndexList selectedIndix=theSelection->selectedIndexes();

    QModelIndex aIndex;
    QStandardItem   *aItem;
    QFont   font;

    for (int i=0;i<selectedIndix.count();i++)
    {
        aIndex=selectedIndix.at(i);
        aItem=theModel->itemFromIndex(aIndex);
        font=aItem->font();
        font.setBold(checked);
        aItem->setFont(font);
    }

}

void MainWindow::on_actAlignLeft_triggered()
{
    if (!theSelection->hasSelection())
        return;

    QModelIndexList selectedIndix=theSelection->selectedIndexes();

    QModelIndex aIndex;
    QStandardItem   *aItem;

    for (int i=0;i<selectedIndix.count();i++)
    {
        aIndex=selectedIndix.at(i);
        aItem=theModel->itemFromIndex(aIndex);
        aItem->setTextAlignment(Qt::AlignLeft);
    }
}

void MainWindow::on_actAlignRight_triggered()
{
    if (!theSelection->hasSelection())
        return;

    QModelIndexList selectedIndix=theSelection->selectedIndexes();

    QModelIndex aIndex;
    QStandardItem   *aItem;

    for (int i=0;i<selectedIndix.count();i++)
    {
        aIndex=selectedIndix.at(i);
        aItem=theModel->itemFromIndex(aIndex);
        aItem->setTextAlignment(Qt::AlignRight);
    }
}

void MainWindow::on_actTabReset_triggered()
{//表格復位
    resetTable(10);
}

void MainWindow::on_actSaveBin_triggered()
{//保存二進制文件
    QString curPath=QDir::currentPath();
    //調用打開文件對話框選擇一個文件
    QString aFileName=QFileDialog::getSaveFileName(this,tr("選擇保存文件"),curPath,
                                                   "二進制數據文件(*.dat)");
    if (aFileName.isEmpty())
        return; //

    if  (saveBinaryFile(aFileName)) //保存為流數據文件
        QMessageBox::information(this,"提示消息","文件已經成功保存!");
}

void MainWindow::on_actOpenBin_triggered()
{//打開二進制文件
    QString curPath=QDir::currentPath();//系統當前目錄
    QString aFileName=QFileDialog::getOpenFileName(this,tr("打開一個文件"),curPath,
                                                   "二進制數據文件(*.dat)");
    if (aFileName.isEmpty())
        return; //

    if  (openBinaryFile(aFileName)) //保存為流數據文件
        QMessageBox::information(this,"提示消息","文件已經打開!");
}

到了這里,關于07-2_Qt 5.9 C++開發(fā)指南_二進制文件讀寫(stm和dat格式)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 09-1_Qt 5.9 C++開發(fā)指南_Qchart概述

    09-1_Qt 5.9 C++開發(fā)指南_Qchart概述

    Qt Charts 可以很方便地繪制常見的折線圖、柱狀圖、餅圖等圖表,不用自己耗費時間和精力開發(fā)繪圖組件或使用第三方組件了。 本章首先介紹 Qt Charts 的基本特點和功能,以畫折線圖為例詳細說明 Qt Charts 各主要部件的操作方法,再介紹各種常用圖表的繪圖方法,最后介紹鼠標

    2024年02月13日
    瀏覽(69)
  • 16-4_Qt 5.9 C++開發(fā)指南_Qt 應用程序的發(fā)布

    用 Qt 開發(fā)一個應用程序后,將應用程序提供給用戶在其他計算機上使用就是應用程序的發(fā)布。應用程序發(fā)布一般會提供一個安裝程序,將應用程序的可執(zhí)行文件及需要的運行庫安裝到用戶計算機上,即使用戶計算機上沒有安裝 Qt 也能正常運行安裝的程序。 Qt的應用程序發(fā)布

    2024年02月14日
    瀏覽(95)
  • 15-1_Qt 5.9 C++開發(fā)指南_Qt多媒體模塊概述

    15-1_Qt 5.9 C++開發(fā)指南_Qt多媒體模塊概述

    多媒體功能指的主要是計算機的音頻和視頻的輸入、輸出、顯示和播放等功能,Qt 的多媒體模塊為音頻和視頻播放、錄音、攝像頭拍照和錄像等提供支持,甚至還提供數字收音機的支持。本章將介紹 Qt 多媒體模塊的功能和使用。 Qt 多媒體模塊提供了很多類,可以實現如下的

    2024年02月13日
    瀏覽(39)
  • 12-4_Qt 5.9 C++開發(fā)指南_創(chuàng)建和使用共享庫

    12-4_Qt 5.9 C++開發(fā)指南_創(chuàng)建和使用共享庫

    除了靜態(tài)庫,Qt 還可以創(chuàng)建共享庫, 也就是 Windows 平臺上的動態(tài)鏈接庫 。動態(tài)鏈接庫項目編譯后生成 DLL 文件,DLL 文件在 windows 平臺上應用廣泛。DLL 文件是在應用程序運行時加載的,不像靜態(tài)庫那樣在編譯期間就連編到應用程序里。若更新了 DLL 文件版本,只要接口未變,

    2024年02月14日
    瀏覽(31)
  • 04-6_Qt 5.9 C++開發(fā)指南_QListWidget和QToolButton

    04-6_Qt 5.9 C++開發(fā)指南_QListWidget和QToolButton

    Qt 中用于項 (Item)處理的組件有兩類, 一類是 Item Views ,包括 QListView、QTreeView、QTableView、QColumnView 等; 另一類是 Item Widgets ,包括 QListWidget、QTreeWidget 和QTableWidget。 Item Views 基于模型/視圖(Model/Vicw)結構,視圖 (View)與模型數據(Model Data)關聯實現數據的顯示和編輯,模型/視圖結

    2024年02月13日
    瀏覽(31)
  • 04-5_Qt 5.9 C++開發(fā)指南_QComboBox和QPlainTextEdit

    04-5_Qt 5.9 C++開發(fā)指南_QComboBox和QPlainTextEdit

    QComboBox 是下拉列表框組件類,它提供一個下拉列表供用戶選擇,也可以直接當作一個QLineEdit 用作輸入。OComboBox 除了顯示可見下拉列表外,每個項 (item,或稱列表項)還可以關聯一個 QVariant 類型的變量,用于存儲一些不可見數據。 QPlainTextEdit 是一個多行文本編輯器,用于顯示

    2024年02月14日
    瀏覽(30)
  • 04-4_Qt 5.9 C++開發(fā)指南_時間日期與定時器

    04-4_Qt 5.9 C++開發(fā)指南_時間日期與定時器

    時間日期是經常遇到的數據類型,Qt 中時間日期類型的類如下。 QTime:時間數據類型,僅表示時間,如 15:23:13。 QDate:日期數據類型,僅表示日期,如2017-4-5. QDateTime:日期時間數據類型,表示日期和時間,如2017-03-23 08:12:43. Qt 中有專門用于日期、時間編輯和顯示的 界面組件 ,介

    2024年02月14日
    瀏覽(34)
  • 08-3_Qt 5.9 C++開發(fā)指南_Graphics View繪圖架構

    08-3_Qt 5.9 C++開發(fā)指南_Graphics View繪圖架構

    采用QPainter 繪圖時需要在繪圖設備的 paintEvent()事件里編寫繪圖的程序,實現整個繪圖過程。這種方法如同使用 Windows 的畫圖軟件在繪圖,繪制的圖形是位圖,這種方法適合于繪制復雜性不高的固定圖形,不能實現圖件的選擇、編輯、拖放、修改等功能。 Qt 為繪制復雜的可交

    2024年02月13日
    瀏覽(28)
  • 06-2_Qt 5.9 C++開發(fā)指南_自定義對話框及其調用

    06-2_Qt 5.9 C++開發(fā)指南_自定義對話框及其調用

    本篇介紹到的對話框及其調用實例較為復雜但十分詳細,如果做了解可以先參考:QT從入門到實戰(zhàn)x篇_13_模態(tài)和非模態(tài)對話框創(chuàng)建。 在一個應用程序設計中,為了實現一些特定的功能,必須設計自定義對話框。自定義對話框的設計一般從QDialog 繼承,并且可以采用 UI 設計器可

    2024年02月13日
    瀏覽(36)
  • 14-5_Qt 5.9 C++開發(fā)指南_基于HTTP 協議的網絡應用程序

    14-5_Qt 5.9 C++開發(fā)指南_基于HTTP 協議的網絡應用程序

    Qt 網絡模塊提供一些類實現 OSI 7 層網絡模型中高層的網絡協議,如 HTTP、FTP、SNMP等,這些類主要是 QNetworkRequest、QNetworkReply和QNetworkAccessManager。 QNetworkRequest 類通過一個URL 地址發(fā)起網絡協議請求,也保存網絡請求的信息,目前支持 HTTP、FTP 和局部文件 URLs的下載或上傳。 QNe

    2024年02月13日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包