Qt解析.csv文件到表格(QTableView)


QTableView

  • 自定义的CSVTabel类继承自QTableView,解析.csv文件到QStandardItem组织的表格,单项可编辑并修改到文件。
  • dataChanged信号一写入数据就会被触发,要注意一下。

表格

在这里插入图片描述

.h

#ifndef CSVTABEL_H
#define CSVTABEL_H

#include <QWidget>
#include <QTableView>
#include <QHeaderView>
#include <QStandardItem>
#include <QFile>
#include <QMessageBox>
#include <QDebug>

class CSVTabel : public QTableView
{
    Q_OBJECT
public:
    explicit CSVTabel(QWidget *parent = nullptr);

    bool getCsvTable(const QString &path); //供外部调用,传入.csv文件路径,得到表格

    QString filePath(){return m_filePath;}
    void setFilePath(const QString& path){m_filePath = path;}
private:
    QStandardItemModel* m_model; //表格模型
    QString m_filePath; //.csv文件路径
    bool addLines(const QString &path);  //将文件解析到表格
    bool m_dataChanged = false;  //浅浅挡一下dataChanged这个鬼信号

    bool setToFile(int row,int column,const QString& data); //修改文件第row行column列的数据为data
};

#endif // CSVTABEL_H

.c

#include "csvtabel.h"


CSVTabel::CSVTabel(QWidget *parent) : QTableView(parent)
{
    m_model = new QStandardItemModel(this);

    //将修改的数据同步到文件
    connect(m_model,&QStandardItemModel::dataChanged,this,[=](QModelIndex index){
        if(!m_dataChanged) //不好意思,您请回吧!
            return ;

        if(QMessageBox::No == QMessageBox::question(this,"修改文件","确定修改项到文件?")){
            m_dataChanged = false;  //加锁(不是
            m_model->setData(index,m_model->item(index.row(),index.column())->toolTip());
            m_dataChanged = true;
            return ;
        }
        QString data = m_model->itemFromIndex(index)->text();

        setToFile(index.row(),index.column(),data);
        m_dataChanged = false;
        m_model->setData(index,data);
        m_model->item(index.row(),index.column())->setToolTip(data);
        m_dataChanged = true;

    });

}

//供外部调用,传入.csv文件路径,得到表格
bool CSVTabel::getCsvTable(const QString &path)
{
    m_dataChanged = false;
    m_filePath = path;
    m_model->clear();

    if(!addLines(path))
        return false;

    this->setModel(m_model);

    m_dataChanged = true;
    return true;
}

//修改文件第row行column列的数据为data
bool CSVTabel::setToFile(int row, int column, const QString &data)
{
    QFile file(m_filePath);

    if(!file.open(QFile::ReadOnly | QFile::Text))
        return false;

    QStringList lines = QString(file.readAll()).split("\n");
    file.close();
    if(!(file.error() == QFile::NoError))
        return false;

    //将数据写入临时文件成功后删除原文件再把临时文件改名
    QFile tmpFile(m_filePath+".tmp");
    tmpFile.open(QFile::WriteOnly | QFile::Truncate | QFile::Text);

    QStringList strItems = lines[row].split(",");
    strItems[column] = data;
    for(int i =0; i<lines.count(); i++){
        if(i == row){
            for(int j=0; j < strItems.count(); j++){
                tmpFile.write(strItems[j].toStdString().c_str());
                if(j == strItems.count()-1) //行尾不写","
                    break;
                tmpFile.write(",");
            }
            tmpFile.write("\n");
            continue;
        }

        tmpFile.write(lines[i].toStdString().c_str());
        if(i == lines.count()-1) //最后一行不写"\n"
            break;
        tmpFile.write("\n");
    }

    if(tmpFile.error() == QFile::NoError){
        if(file.remove()){
            tmpFile.rename(m_filePath);
            return  true;
        }
    }

    tmpFile.close();
    tmpFile.remove();
    return false;
}

//将文件解析到表格
bool CSVTabel::addLines(const QString &path)
{
    int row = 0,column = 0;
    QString line;
    QStringList strItem;

    QFile file(path);
    if(!file.open(QFile::ReadOnly | QFile::Text))
        return false;

    while(!file.atEnd()){
        line.clear();
        strItem.clear();
        line = file.readLine();
        line.remove(line.size()-1,1); //"\n去掉"
        if(line.isEmpty()){
            qDebug()<< "[" << QString::number(row)<<"]行出现空行,已跳过";
            row++;
            continue;
        }
        strItem = line.split(","); //逗号分割
//        qDebug()<<strItem;

        if(row == 0){ //起始行确定列数
            column = strItem.size();
        }

        if(column != strItem.size() || !(file.error() == QFile::NoError)){
            qDebug()<<"解析文件出错";
            return  false;
        }

        for(int i=0; i < column; i++){
            QStandardItem* childItem = new QStandardItem(strItem[i]);
            childItem->setToolTip(strItem[i]);
            m_model->setItem(row,i,childItem);
        }
        row++;
    }

    return true;
}

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
Qt中,你可以按照以下步骤将.csv文件导入QTableView: 1. 创建一个QStandardItemModel对象,用于存储.csv文件中的数据 2. 读取.csv文件中的数据,并将数据存储到QStandardItemModel对象中 3. 创建一个QTableView对象,用于显示数据 4. 将QStandardItemModel对象设置为QTableView对象的model 以下是示例代码: ```cpp #include <QStandardItemModel> #include <QFile> #include <QTextStream> #include <QTableView> void MainWindow::loadCsvFile(QString filePath) { // 创建一个QStandardItemModel对象 QStandardItemModel* model = new QStandardItemModel(); // 读取.csv文件中的数据,并将数据存储到QStandardItemModel对象中 QFile file(filePath); if (file.open(QFile::ReadOnly | QFile::Text)) { QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine(); QStringList fields = line.split(","); QList<QStandardItem*> items; for (QString field : fields) { items.append(new QStandardItem(field)); } model->appendRow(items); } file.close(); } // 创建一个QTableView对象,用于显示数据 QTableView* tableView = new QTableView(); // 将QStandardItemModel对象设置为QTableView对象的model tableView->setModel(model); // 设置表格为自适应大小 tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 将QTableView添加到主窗口中 setCentralWidget(tableView); } ``` 在上面的示例代码中,我们首先创建了一个QStandardItemModel对象,然后使用QFile和QTextStream读取.csv文件中的数据,并将数据存储到QStandardItemModel对象中。接着,创建一个QTableView对象,并将QStandardItemModel对象设置为QTableView对象的model,最后将QTableView添加到主窗口中。运行程序后,就可以看到.csv文件中的数据显示在了QTableView中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

money的大雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值