QT-C++ 自定义加工统计通用模块

QT-C++ 自定义加工统计通用模块


一、演示效果

二、核心程序

c 复制代码
#include "ProcessingStatisticsModule.h"
#include <QSqlError>
#include <QSqlRecord>
#include <QFile>
#include <QTextStream>
#include <QDebug>

ProcessingStatisticsManager::ProcessingStatisticsManager(const QString& dbName, QObject *parent)
    : QObject(parent), m_dbName(dbName)
{
}

ProcessingStatisticsManager::~ProcessingStatisticsManager()
{
    if (m_db.isOpen()) {
        m_db.close();
    }
}

bool ProcessingStatisticsManager::initialize()
{
    // 移除可能存在的旧连接
    if (QSqlDatabase::contains("stats_connection")) {
        m_db = QSqlDatabase::database("stats_connection");
    } else {
        // 创建新的SQLite连接
        m_db = QSqlDatabase::addDatabase("QSQLITE", "stats_connection");
    }
    
    m_db.setDatabaseName(m_dbName);
    
    if (!m_db.open()) {
        m_lastError = m_db.lastError().text();
        return false;
    }
    
    return true;
}

bool ProcessingStatisticsManager::tableExists(const QString& tableName)
{
    QSqlQuery query(m_db);
    QString sql = QString("SELECT name FROM sqlite_master WHERE type='table' AND name='%1'").arg(tableName);
    
    if (!query.exec(sql)) {
        m_lastError = query.lastError().text();
        return false;
    }
    
    return query.next();
}

bool ProcessingStatisticsManager::createStatisticsTable(const QString& tableName, const QList<FieldInfo>& fields)
{
    if (tableExists(tableName)) {
        m_lastError = QString("Table %1 already exists").arg(tableName);
        return false;
    }
    
    QString sql = QString("CREATE TABLE %1 (").arg(tableName);
    
    // 添加日期字段,所有表都包含日期字段
    sql += "date DATE NOT NULL, ";
    
    // 添加用户定义的字段
    for (int i = 0; i < fields.size(); ++i) {
        const FieldInfo& field = fields[i];
        sql += QString("%1 %2").arg(field.name).arg(field.type);
        
        if (field.isPrimaryKey) {
            sql += " PRIMARY KEY";
        }
        
        if (i != fields.size() - 1) {
            sql += ", ";
        }
    }
    
    sql += ")";
    
    QSqlQuery query(m_db);
    if (!query.exec(sql)) {
        m_lastError = query.lastError().text();
        return false;
    }
    
    return true;
}

QStringList ProcessingStatisticsManager::getAllTables()
{
    QStringList tables;
    QSqlQuery query(m_db);
    
    if (query.exec("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")) {
        while (query.next()) {
            QString tableName = query.value(0).toString();
            // 排除SQLite系统表
            if (tableName != "sqlite_sequence") {
                tables.append(tableName);
            }
        }
    } else {
        m_lastError = query.lastError().text();
    }
    
    return tables;
}

QList<FieldInfo> ProcessingStatisticsManager::getTableFields(const QString& tableName)
{
    QList<FieldInfo> fields;
    
    if (!tableExists(tableName)) {
        m_lastError = QString("Table %1 does not exist").arg(tableName);
        return fields;
    }
    
    QSqlQuery query(m_db);
    if (query.exec(QString("PRAGMA table_info(%1)").arg(tableName))) {
        while (query.next()) {
            // PRAGMA table_info返回的字段顺序:0=cid, 1=name, 2=type, 3=notnull, 4=dflt_value, 5=pk
            FieldInfo field;
            field.name = query.value(1).toString();
            field.type = query.value(2).toString();
            field.isPrimaryKey = (query.value(5).toInt() == 1);
            
            // 跳过date字段,它是系统自动添加的
            if (field.name != "date") {
                fields.append(field);
            }
        }
    } else {
        m_lastError = query.lastError().text();
    }
    
    return fields;
}

bool ProcessingStatisticsManager::checkFieldsExist(const QString& tableName, const QVariantMap& data)
{
    QList<FieldInfo> fields = getTableFields(tableName);
    if (fields.isEmpty() && !m_lastError.isEmpty()) {
        return false;
    }
    
    QStringList fieldNames;
    for (const auto& field : fields) {
        fieldNames.append(field.name);
    }
    
    // 检查数据中的所有键是否都存在于表字段中
    for (const QString& key : data.keys()) {
        if (!fieldNames.contains(key)) {
            m_lastError = QString("Field '%1' does not exist in table '%2'").arg(key).arg(tableName);
            return false;
        }
    }
    
    return true;
}

bool ProcessingStatisticsManager::addStatisticsData(const QString& tableName, const QVariantMap& data, const QDate& date)
{
    if (!tableExists(tableName)) {
        m_lastError = QString("Table %1 does not exist").arg(tableName);
        return false;
    }
    
    if (!checkFieldsExist(tableName, data)) {
        return false;
    }
    
    QString sql = QString("INSERT INTO %1 (date, %2) VALUES ('%3', %4)")
                    .arg(tableName)
                    .arg(data.keys().join(", "))
                    .arg(date.toString("yyyy-MM-dd"));
    
    QStringList valuePlaceholders;
    for (int i = 0; i < data.size(); ++i) {
        valuePlaceholders.append("?");
    }
    sql = sql.arg(valuePlaceholders.join(", "));
    
    QSqlQuery query(m_db);
    query.prepare(sql);
    
    int index = 0;
    for (const QVariant& value : data.values()) {
        query.bindValue(index++, value);
    }
    
    if (!query.exec()) {
        m_lastError = query.lastError().text();
        return false;
    }
    
    return true;
}

bool ProcessingStatisticsManager::updateStatisticsData(const QString& tableName, const QVariantMap& data, const QString& whereClause)
{
    if (!tableExists(tableName)) {
        m_lastError = QString("Table %1 does not exist").arg(tableName);
        return false;
    }
    
    if (!checkFieldsExist(tableName, data)) {
        return false;
    }
    
    QStringList setClauses;
    for (const QString& key : data.keys()) {
        setClauses.append(QString("%1 = ?").arg(key));
    }
    
    QString sql = QString("UPDATE %1 SET %2 WHERE %3")
                    .arg(tableName)
                    .arg(setClauses.join(", "))
                    .arg(whereClause);
    
    QSqlQuery query(m_db);
    query.prepare(sql);
    
    int index = 0;
    for (const QVariant& value : data.values()) {
        query.bindValue(index++, value);
    }
    
    if (!query.exec()) {
        m_lastError = query.lastError().text();
        return false;
    }
    
    return true;
}

QSqlQuery ProcessingStatisticsManager::queryByDateRange(const QString& tableName, const QDate& startDate, 
                                                       const QDate& endDate, const QStringList& fields)
{
    QSqlQuery query(m_db);
    
    if (!tableExists(tableName)) {
        m_lastError = QString("Table %1 does not exist").arg(tableName);
        return query;
    }
    
    QString selectFields = "*";
    if (!fields.isEmpty()) {
        selectFields = fields.join(", ") + ", date"; // 确保包含日期字段
    }
    
    QString sql = QString("SELECT %1 FROM %2 WHERE date BETWEEN '%3' AND '%4' ORDER BY date")
                    .arg(selectFields)
                    .arg(tableName)
                    .arg(startDate.toString("yyyy-MM-dd"))
                    .arg(endDate.toString("yyyy-MM-dd"));
    
    if (!query.exec(sql)) {
        m_lastError = query.lastError().text();
    }
    
    return query;
}

QSqlQuery ProcessingStatisticsManager::customQuery(const QString& queryStr)
{
    QSqlQuery query(m_db);
    if (!query.exec(queryStr)) {
        m_lastError = query.lastError().text();
    }
    return query;
}

bool ProcessingStatisticsManager::exportTableToCSV(const QString& tableName, const QString& filePath, const QString& delimiter)
{
    if (!tableExists(tableName)) {
        m_lastError = QString("Table %1 does not exist").arg(tableName);
        return false;
    }
    
    QSqlQuery query = customQuery(QString("SELECT * FROM %1 ORDER BY date").arg(tableName));
    return exportQueryToCSV(query, filePath, delimiter);
}

bool ProcessingStatisticsManager::exportQueryToCSV(QSqlQuery& query, const QString& filePath, const QString& delimiter)
{
    if (!query.isActive()) {
        m_lastError = "Invalid query";
        return false;
    }
    
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        m_lastError = file.errorString();
        return false;
    }
    
    QTextStream out(&file);
    
    // 写入表头
    QSqlRecord record = query.record();
    for (int i = 0; i < record.count(); ++i) {
        if (i > 0) {
            out << delimiter;
        }
        out << record.fieldName(i);
    }
    out << "\n";
    
    // 写入数据
    while (query.next()) {
        for (int i = 0; i < record.count(); ++i) {
            if (i > 0) {
                out << delimiter;
            }
            out << query.value(i).toString();
        }
        out << "\n";
    }
    
    file.close();
    return true;
}

bool ProcessingStatisticsManager::exportDateRangeToCSV(const QString& tableName, const QDate& startDate, 
                                                     const QDate& endDate, const QString& filePath, 
                                                     const QString& delimiter)
{
    QSqlQuery query = queryByDateRange(tableName, startDate, endDate);
    return exportQueryToCSV(query, filePath, delimiter);
}

三、下载链接

https://download.csdn.net/download/u013083044/92121187

相关推荐
好好沉淀16 分钟前
Elasticsearch 中获取返回匹配记录总数
开发语言·elasticsearch
xu_yule19 分钟前
网络和Linux网络-13(高级IO+多路转接)五种IO模型+select编程
linux·网络·c++·select·i/o
2301_7657031426 分钟前
C++与自动驾驶系统
开发语言·c++·算法
轩情吖29 分钟前
Qt的窗口(三)
c++·qt
MediaTea30 分钟前
<span class=“js_title_inner“>Python:实例对象</span>
开发语言·前端·javascript·python·ecmascript
热爱编程的小刘39 分钟前
Lesson04---类与对象(下篇)
开发语言·c++·算法
毕设源码-朱学姐42 分钟前
【开题答辩全过程】以 基于Java的九价疫苗预约系统为例,包含答辩的问题和答案
java·开发语言
雨季6661 小时前
Flutter 三端应用实战:OpenHarmony “微光笔记”——在灵感消逝前,为思想点一盏灯
开发语言·javascript·flutter·ui·dart
yugi9878381 小时前
遗传算法优化的极限学习机模型(GA-ELM)Matlab实现
开发语言·matlab
梦梦代码精1 小时前
开源、免费、可商用:BuildingAI一站式体验报告
开发语言·前端·数据结构·人工智能·后端·开源·知识图谱