如何读取.txt文件表头并在QTableView中正确分栏显示
问题
解析.txt文件并在QTableView中展示时,无法正确提取表头并分栏显示。文件首行为表头,其余为数据,目前所有内容都挤在一列里,尽管用了split方法拆分字符串。
示例文件内容
表头行
tax_id Org_name GeneID CurrentID Status Symbol Aliases description other_designations map_location chromosome genomic_nucleotide_accession.version start_position_on_the_genomic_accession end_position_on_the_genomic_accession orientation exon_count OMIM
数据行示例
1041930 Methanocella conradii HZ254 11971032 0 live mRNA MTC_RS04550, Mtc_0908 coenzyme-B sulfoethylthiotransferase subunit alpha coenzyme-B sulfoethylthiotransferase subunit alpha NC_017034.1 886220 887887 plus 0 79929 Methanothermobacter marburgensis str. Marburg 9705221 0 live mRNA MTBMA_RS07375, MTBMA_c15120 coenzyme-B sulfoethylthiotransferase subunit alpha coenzyme-B sulfoethylthiotransferase subunit alpha NC_014408.1 1393293 1394954 minus 0 523846 Methanothermus fervidus DSM 2088 9962464 0 live mRNA MFER_RS03735, Mfer_0734 coenzyme-B sulfoethylthiotransferase subunit alpha coenzyme-B sulfoethylthiotransferase subunit alpha NC_014658.1 713917 715581 plus 0
当前错误效果
所有内容显示在单一列中,无法按表头分栏。
预期效果
按表头分成对应列,呈现类似Excel打开后的规整表格样式。
当前实现代码
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); model = new QStandardItemModel(this); ui->tableView->setModel(model); ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); setWindowTitle("Viewer Example"); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_loadTXTBtn_clicked() { auto filename = QFileDialog::getOpenFileName(this, "Open", QDir::rootPath(), "txt file (*.txt)"); if(filename.isEmpty()) { return; } QFile file(filename); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return; } QTextStream xin(&file); int ix = 0; while (!xin.atEnd()) { model->setRowCount(ix); auto line = xin.readLine(); auto values = line.split(" "); const int colCount = values.size(); model->setColumnCount(colCount); for(int jx = 0; jx < colCount; ++jx) { setValueAt(ix, jx, values.at(jx)); } ++ix; ui->pathLineEdit->setText(filename); } file.close(); } void MainWindow::setValueAt(int ix, int jx, const QString &value) { if (!model->item(ix, jx)) { model->setItem(ix, jx, new QStandardItem(value)); } else { model->item(ix, jx)->setText(value); } }
解决方法
1. 修正字符串拆分逻辑
核心问题是拆分字符串的分隔符错误:示例文件用**制表符(Tab)**分隔列,而非三个空格。当前用line.split(" ")拆分,导致大部分内容无法正确分割,全部挤在一列。
替换为按制表符拆分,并忽略空内容:
auto values = line.split("\t", Qt::SkipEmptyParts);
Qt::SkipEmptyParts可避免连续制表符产生的空字符串,防止出现多余空列。
2. 单独处理表头行
文件首行是表头,需单独提取并设置为QTableView的水平表头,而非作为普通数据行:
修改on_loadTXTBtn_clicked函数:
void MainWindow::on_loadTXTBtn_clicked() { auto filename = QFileDialog::getOpenFileName(this, "Open", QDir::rootPath(), "txt file (*.txt)"); if(filename.isEmpty()) { return; } QFile file(filename); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return; } QTextStream xin(&file); // 清空原有模型数据 model->clear(); // 读取并设置表头 QString headerLine = xin.readLine(); QStringList headers = headerLine.split("\t", Qt::SkipEmptyParts); model->setColumnCount(headers.size()); model->setHorizontalHeaderLabels(headers); int ix = 0; while (!xin.atEnd()) { QString line = xin.readLine().trimmed(); if(line.isEmpty()) continue; // 跳过空行 QStringList values = line.split("\t", Qt::SkipEmptyParts); // 确保列数与表头一致,避免越界 int colCount = qMin(values.size(), model->columnCount()); for(int jx = 0; jx < colCount; ++jx) { setValueAt(ix, jx, values.at(jx).trimmed()); } ++ix; model->setRowCount(ix); } ui->pathLineEdit->setText(filename); file.close(); }
3. 优化模型操作逻辑
- 读取文件前调用
model->clear()清空旧数据,避免重复加载时混乱 - 数据行循环中,先拆分内容再设置行数量,减少冗余操作
- 用
qMin限制列数,防止数据行列数与表头不一致时出现索引越界 - 对每个值调用
trimmed()去除前后空格,避免单元格内容带多余空白
4. 验证效果
修改后,QTableView会正确识别制表符分隔的列,同时将首行设置为水平表头,实现与Excel一致的规整展示效果。
内容的提问来源于stack exchange,提问作者EsoMars
相关产品推荐
相关产品推荐

