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

.csv表格

    • QTableView
    • 表格
    • .h
    • .c


QTableView

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

表格

Qt解析.csv文件到表格(QTableView)_第1张图片

.h

#ifndef CSVTABEL_H
#define CSVTABEL_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 

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

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

你可能感兴趣的:(娶她,qt,c++,windows)