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);
QString filePath(){return m_filePath;}
void setFilePath(const QString& path){m_filePath = path;}
private:
QStandardItemModel* m_model;
QString m_filePath;
bool addLines(const QString &path);
bool m_dataChanged = false;
bool setToFile(int row,int column,const QString& data);
};
#endif
.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;
});
}
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;
}
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)
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);
if(line.isEmpty()){
qDebug()<< "[" << QString::number(row)<<"]行出现空行,已跳过";
row++;
continue;
}
strItem = line.split(",");
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;
}