2024-09-08第二波的二进制读写

1.



3.



03



.



44


创建的 表格:



03


void on_actTabReset_triggered(); //表格复位




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); //不可编辑 }}


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;irowCount();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); //不可编辑

    }

}




下一个hasn't函数:


02


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,"提示消息","文件已经打开!");

}




分析:

你的代码是一个槽函数 `on_actOpen_triggered()` 的实现,用于响应用户打开文件的操作。下面是对这段代码的详细分析:

### 代码功能概述

1. **获取当前工作目录:**

  ```cpp

  QString curPath = QDir::currentPath();

  ```

  这行代码获取了当前的工作目录,并将其存储在 `curPath` 变量中。这个目录将作为文件对话框的默认路径。

2. **打开文件对话框:**

  ```cpp

  QString aFileName = QFileDialog::getOpenFileName(

      this, tr("打开一个文件"), curPath, "流数据文件(*.stm)"

  );

  ```

  这行代码弹出一个文件对话框,允许用户选择一个文件。`getOpenFileName` 函数的参数分别是:

  - `this`:当前窗口的指针。

  - `tr("打开一个文件")`:对话框的标题。

  - `curPath`:对话框初始显示的路径。

  - `"流数据文件(*.stm)"`:文件过滤器,只显示扩展名为 `.stm` 的文件。

  函数返回选择的文件的路径,如果用户取消了对话框,`aFileName` 将为空。

3. **检查文件名是否为空:**

  ```cpp

  if (aFileName.isEmpty())

      return;

  ```

  如果用户取消了文件选择对话框,`aFileName` 会为空,代码会直接返回,不继续执行后续操作。

4. **打开文件并显示提示消息:**

  ```cpp

  if (openDataAsStream(aFileName))

      QMessageBox::information(this, "提示消息", "文件已经打开!");

  ```

  `openDataAsStream(aFileName)` 是一个自定义函数(假设它是一个成员函数或在其他地方定义的函数),用于打开指定的文件。如果文件成功打开,函数返回 `true`,然后显示一个信息框,告知用户文件已经成功打开。

### 代码改进建议

1. **错误处理**:

  - 目前代码只在文件成功打开时显示消息框,但没有处理文件打开失败的情况。建议添加文件打开失败的错误处理代码,例如:

    ```cpp

    if (openDataAsStream(aFileName)) {

        QMessageBox::information(this, "提示消息", "文件已经打开!");

    } else {

        QMessageBox::warning(this, "打开文件失败", "无法打开选定的文件。");

    }

    ```

2. **改进文件过滤器**:

  - 文件过滤器 `"流数据文件(*.stm)"` 可以考虑加入更多的文件类型,或者将过滤器提取到常量中以便维护。例如:

    ```cpp

    const QString filter = "流数据文件(*.stm);;所有文件(*.*)";

    QString aFileName = QFileDialog::getOpenFileName(this, tr("打开一个文件"), curPath, filter);

    ```

3. **确保 `openDataAsStream` 的正确实现**:

  - 代码中假设 `openDataAsStream` 函数已经实现并正确工作。如果 `openDataAsStream` 有可能抛出异常或返回错误,确保它的实现是健壮的并且可以正确处理各种情况。

4. **本地化支持**:

  - 如果你的应用需要多语言支持,确保使用 `tr()` 进行字符串本地化。你已经在对话框标题中使用了 `tr()`,确保所有用户界面字符串都使用 `tr()` 进行本地化,以便在不同语言环境下能正确显示。

通过这些改进,可以使你的代码更加健壮、灵活且用户友好。



不懂就问:



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; //列数




完整的 :


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;  //读取表头字符串


    //获取数据区文字,

    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;

}




第 三 个的;



//3.0

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预定义编码方式

    }



//获取数据区的数据

    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;

}




第 四 个的;void on_actOpenBin_triggered(); //4.打开自编码二进制文件


//4.

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,"提示消息","文件已经打开!");

}




封装的函数 :


//4.

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

    {

        aStream.readBytes(buf,strLen);//同时读取字符串长度,和字符串内容

        QString str=QString::fromLocal8Bit(buf,strLen); //可处理汉字

    }

//获取数据区数据

    QStandardItem  *aItem;

    qint16  ceShen;

    qreal  chuiShen;

    qreal  fangWei;

    qreal  weiYi;

    QString  zhiLiang;

    qint8  quYang; //分别代表逻辑值 true和false

    QModelIndex index;

    for (int i=0;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;

}





void on_actSaveBin_triggered(); //5.保存为自编码二进制文件


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,"提示消息","文件已经成功保存!");

}









下面的 看 主函数 :



MainWindow::MainWindow(QWidget *parent) :

    QMainWindow(parent),

    ui(new Ui::MainWindow)

{

    ui->setupUi(this);


    theModel = new QStandardItemModel(5,FixedColumnCount,this); //创建数据模型

    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); //


//创建状态栏组件

    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);

}






这么晚

怎么玩的 :

分析:

这段代码是一个 Qt 应用程序中 `MainWindow` 类的构造函数实现。`MainWindow` 继承自 `QMainWindow`,用于设置主窗口的初始状态和初始化组件。下面是对这段代码的详细分析:

### 1. **构造函数初始化列表**

```cpp

MainWindow::MainWindow(QWidget *parent) :

    QMainWindow(parent),

    ui(new Ui::MainWindow)

{

```

- `QMainWindow(parent)`:调用基类 `QMainWindow` 的构造函数,并将父窗口指针 `parent` 传递给它。这确保了 `MainWindow` 可以作为其他窗口的子窗口。

- `ui(new Ui::MainWindow)`:初始化 `ui` 指针,`Ui::MainWindow` 是由 Qt 的用户界面设计器(Qt Designer)生成的类,用于设置和管理窗口的控件。

### 2. **设置 UI**

```cpp

    ui->setupUi(this);

```

- `setupUi(this)`:调用 `Ui::MainWindow` 的 `setupUi` 方法,用于初始化界面组件并将它们添加到 `MainWindow` 中。

### 3. **创建和设置数据模型**

```cpp

    theModel = new QStandardItemModel(5, FixedColumnCount, this); // 创建数据模型

    QStringList headerList;

    headerList << "Depth" << "Measured Depth" << "Direction" << "Offset" << "Quality" << "Sampled";

    theModel->setHorizontalHeaderLabels(headerList); // 设置表头文字

```

- `QStandardItemModel(5, FixedColumnCount, this)`:创建一个 `QStandardItemModel` 实例,具有 5 行和 `FixedColumnCount` 列(`FixedColumnCount` 应该是一个预定义的常量或变量,指定列数)。

- `headerList`:一个 `QStringList`,用来定义表格的列标题。

- `setHorizontalHeaderLabels(headerList)`:设置表格的列标题。

### 4. **设置选择模型**

```cpp

    theSelection = new QItemSelectionModel(theModel); // Item选择模型

    connect(theSelection, SIGNAL(currentChanged(QModelIndex, QModelIndex)),

            this, SLOT(on_currentChanged(QModelIndex, QModelIndex)));

```

- `QItemSelectionModel(theModel)`:创建一个 `QItemSelectionModel` 实例,用于管理选中的表格项。

- `connect()`:连接信号和槽。当选择变化时(`currentChanged` 信号),调用 `on_currentChanged` 槽函数。

### 5. **设置表格视图**

```cpp

    ui->tableView->setModel(theModel); // 设置数据模型

    ui->tableView->setSelectionModel(theSelection); // 设置选择模型

```

- `setModel(theModel)`:将创建的数据模型 `theModel` 设置到 `tableView` 中。

- `setSelectionModel(theSelection)`:将选择模型 `theSelection` 设置到 `tableView` 中。

### 6. **设置自定义代理**

```cpp

    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); // ComboBox选择型

```

- `setItemDelegateForColumn(column, delegate)`:为指定列设置自定义代理组件。代理负责处理该列的编辑和显示。例如,整数、浮点数和下拉框选择器。

### 7. **复位表格**

```cpp

    resetTable(5); // 表格复位

```

- `resetTable(5)`:调用 `resetTable` 方法,可能用于初始化或清空表格的数据。具体实现取决于 `resetTable` 函数的定义。

### 8. **设置中央部件**

```cpp

    setCentralWidget(ui->tabWidget); //

```

- `setCentralWidget(ui->tabWidget)`:将 `tabWidget` 设置为 `MainWindow` 的中央部件。`tabWidget` 是 `ui` 中的一个组件,通常用于显示选项卡。

### 9. **创建和设置状态栏组件**

```cpp

    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);

```

- `QLabel`:创建两个标签 `LabCellPos` 和 `LabCellText`,用于在状态栏显示信息。

- `setMinimumWidth()` 和 `setAlignment()`:设置标签的最小宽度和对齐方式。

- `ui->statusBar->addWidget()`:将标签添加到窗口的状态栏中。

### 总结

这段代码是 `MainWindow` 类的构造函数,负责初始化用户界面,包括设置数据模型、选择模型、表格视图、状态栏以及其他 UI 组件。它通过 `Qt` 的信号和槽机制以及自定义代理来处理表格的数据展示和用户交互。




最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容