1.
3.
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函数:
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` 的信号和槽机制以及自定义代理来处理表格的数据展示和用户交互。