输入关键词开始搜索

T016 CSV 导出功能

T016 CSV 导出 — 实现逻辑与核心代码

独立 SQLite 连接 + QDialog + QTextStream 写文件。


一、整体流程

菜单"导出CSV" → MainWindow::onExportCsv()
  → 创建独立 DatabaseManager(不和 ParseWorker 共享连接)
  → 弹出 ExportDialog(模态)
    → 用户选时间范围 + 勾通道 + 点导出
    → QFileDialog 选保存路径
    → QFile → QTextStream
    → m_db.query(from, to) → 遍历 → 写 CSV 行
    → QMessageBox 提示完成

二、核心设计决策

决策选择理由
DB 连接ExportDialog 自建独立连接SQLite 连接不能跨线程共享
对话框类型QDialog(模态)导出时主窗口不可操作,逻辑简单
文件写入QTextStreamQt 内置文本流,自动处理编码
通道选择QCheckBox 数组支持 CH0-7,默认勾 CH0-2
查询上限99999999不设实际限制,由时间范围控制

三、核心代码

ExportDialog::onExport()

void ExportDialog::onExport()
{
    // ① 时间范围
    uint64_t tFrom = m_fromEdit->dateTime().toMSecsSinceEpoch();
    uint64_t tTo   = m_toEdit->dateTime().toMSecsSinceEpoch();

    if (tFrom >= tTo) { QMessageBox::warning(...); return; }

    // ② 勾选的通道
    QVector<int> selected;
    for (int i = 0; i < 8; ++i)
        if (m_chk[i]->isChecked()) selected.append(i);
    if (selected.isEmpty()) { QMessageBox::warning(...); return; }

    // ③ 保存路径
    QString path = QFileDialog::getSaveFileName(this, "保存", "", "CSV(*.csv)");
    if (path.isEmpty()) return;

    // ④ 打开文件
    QFile file(path);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return;
    QTextStream stream(&file);

    // ⑤ 标题行
    QStringList headers; headers << "时间";
    for (int ch : selected) headers << QString("CH%1").arg(ch);
    stream << headers.join(",") << "\n";

    // ⑥ 数据行
    auto results = m_db->query(tFrom, tTo, 99999999);
    for (const auto &dp : results) {
        QStringList row;
        row << QDateTime::fromMSecsSinceEpoch(dp.timestamp)
                   .toString("yyyy-MM-dd hh:mm:ss.zzz");
        for (int ch : selected)
            row << QString::number(dp.channels.value(ch, 0), 'f', 3);
        stream << row.join(",") << "\n";
    }

    file.close();
    QMessageBox::information(this, "完成", QString("已导出 %1 条").arg(results.size()));
    accept();
}

MainWindow 集成

void MainWindow::onExportCsv()
{
    DatabaseManager db;                // 独立连接
    if (!db.init("data.db")) return;
    ExportDialog dialog(&db, this);
    dialog.exec();
}   // db 自动析构

四、关键 API 速查

操作API
时间控件→毫秒QDateTimeEdit::dateTime().toMSecsSinceEpoch()
毫秒→格式化时间QDateTime::fromMSecsSinceEpoch(ms).toString("hh:mm:ss.zzz")
文件保存对话框QFileDialog::getSaveFileName(parent, title, dir, filter)
写文本文件QFile::open(WriteOnly|Text)QTextStream << data << "\n"
double→字符串QString::number(value, 'f', 3) — 保留 3 位小数
模态对话框dialog.exec() — 阻塞,关闭后才返回