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

相关推荐
Rhys..18 小时前
JS - npm init
开发语言·javascript·npm
newxtc18 小时前
【 广州产权交易所-注册安全分析报告-无验证方式导致安全隐患】
开发语言·人工智能·selenium·安全·yolo
兩尛18 小时前
java八股-操作系统
java·开发语言
lingran__18 小时前
算法沉淀第四天(Winner)
c++·算法
wjs202418 小时前
SQL 日期处理指南
开发语言
川石课堂软件测试18 小时前
CSS中常用的几种定位。
开发语言·css·python·网络协议·http·html·pytest
友友马18 小时前
『 QT 』QT信号机制深度解析
开发语言·qt
清风wxy18 小时前
C语言基础数组作业(冒泡算法)
c语言·开发语言·数据结构·c++·windows·算法
我是华为OD~HR~栗栗呀18 小时前
华为OD-21届考研-Java面经
java·前端·c++·python·华为od·华为·面试