C/C++ Qt 数据库与Chart历史数据展示

C/C++ Qt 数据库与Chart历史数据展示攻略

介绍

Qt 是一款跨平台的GUI应用开发框架,它有很多成熟的库和工具,同时也提供了对数据库和数据可视化的支持。这里将介绍如何使用 C++ Qt 开发一个历史数据展示的程序。主要涉及到以下三个方面:

  1. 数据库连接与操作
  2. 数据可视化 (Chart)
  3. 图形界面设计 (UI)

在程序中,我们会使用 MySQL 作为数据库的后端。同时,还会用到 Qt 的 QChart 和 QLineSeries 这些类处理和展示数据。

数据库连接与操作

在 Qt 中,可以使用 QtSQL 模块操作各种关系型数据库。这里我们使用 MySQL 作为后端数据库。连接 MySQL 数据库会用到 Qt 提供的 QSqlDatabase,使用示例如下:

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("database");
db.setUserName("user");
db.setPassword("password");

if (!db.open()) {
    qDebug() << "Failed to connect to database!";
    return;
}

其中,setHostName()setDatabaseName()setUserName()setPassword() 分别用于设置主机名、数据库名、用户名、密码。如果连接成功,open() 函数将返回 true。

QSqlQuery 是 Qt 提供的查询数据库的类。可以使用它执行 SQL 查询,并获取返回的数据。使用示例如下:

QSqlQuery query;
query.exec("SELECT * FROM table");

while (query.next()) {
    QString column1 = query.value(0).toString();
    QString column2 = query.value(1).toString();
    // ...
}

这里的next()函数则是获取到下一行结果。

数据可视化

要实现历史数据的可视化,我们需要使用 Qt 的 QChart 和 QLineSeries 类。其中,QChart 是一个图表对象,QLineSeries 是一个折线图系列。

以下是使用 QChart 和 QLineSeries 显示历史数据的示例:

QChartView *chartView = new QChartView(this);
chartView->setRenderHint(QPainter::Antialiasing);

QChart *chart = new QChart();
chart->setTitle("Temperature History");
QLineSeries *series = new QLineSeries();

QSqlQuery query;
query.exec("SELECT * FROM temperature_history");

while (query.next()) {
    qint64 timestamp = query.value(0).toLongLong();
    double temperature = query.value(1).toDouble();
    QDateTime datetime;
    datetime.setMSecsSinceEpoch(timestamp);
    series->append(datetime.toMSecsSinceEpoch(), temperature);
}

chart->addSeries(series);
chart->createDefaultAxes();

chartView->setChart(chart);
chartView->setRubberBand(QChartView::HorizontalRubberBand);
chartView->setRenderHint(QPainter::Antialiasing);

图形界面设计

Qt 提供了丰富的 UI 组件用于构建图形界面。我们要实现的界面需要包括一个用于展示历史数据的图表和用于过滤数据的时间范围控件。在代码中,我们可以使用 QChartView、QDateTimeEdit 和 QPushButton 来分别实现这些功能。UI 布局可以由 Qt 的 Designer 工具来完成,也可以手动编写代码。

以下是使用 Designer 工具创建历史数据展示程序的界面的步骤:

  1. 打开 Designer 工具,并新建一个空白窗口。
  2. 在 “Widget Box” 中选择 QChartView、QDateTimeEdit 和 QPushButton,并拖拽到窗口中。
  3. 调整上述组件的大小和位置,使其符合需求。
  4. 在界面右键,选择“Layoout”->“Lay Out in a Grid”,实现组件的网格布局。
  5. 在 “Object Inspector” 中对 QChartView、QDateTimeEdit 和 QPushButton 进行命名,并设置好相应的显示文本。保存 UI 文件。

示例程序如下:

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        setWindowTitle("Temperature Monitor");

        QWidget *centralWidget = new QWidget;
        setCentralWidget(centralWidget);

        QGridLayout *layout = new QGridLayout(centralWidget);

        QChartView *chartView = new QChartView(this);
        chartView->setRenderHint(QPainter::Antialiasing);
        layout->addWidget(chartView, 0, 1, 1, 1);

        QDateTimeEdit *startTimeEdit = new QDateTimeEdit(this);
        startTimeEdit->setDateTime(QDateTime::currentDateTime().addDays(-1));
        startTimeEdit->setDisplayFormat("yyyy-MM-dd hh:mm:ss");
        layout->addWidget(startTimeEdit, 1, 0, 1, 1);

        QDateTimeEdit *endTimeEdit = new QDateTimeEdit(this);
        endTimeEdit->setDateTime(QDateTime::currentDateTime());
        endTimeEdit->setDisplayFormat("yyyy-MM-dd hh:mm:ss");
        layout->addWidget(endTimeEdit, 1, 1, 1, 1);

        QPushButton *searchButton = new QPushButton("Search");
        layout->addWidget(searchButton, 1, 2, 1, 1);

        QChart *chart = new QChart();
        chart->setTitle("Temperature History");
        QLineSeries *series = new QLineSeries();
        chart->addSeries(series);
        chart->createDefaultAxes();
        chartView->setChart(chart);

        connect(searchButton, &QPushButton::clicked, [this, series, startTimeEdit, endTimeEdit]() {
            series->clear();

            QSqlQuery query;
            query.prepare("SELECT * FROM temperature_history WHERE timestamp >= ? AND timestamp <= ?");
            query.bindValue(0, startTimeEdit->dateTime().toMSecsSinceEpoch());
            query.bindValue(1, endTimeEdit->dateTime().toMSecsSinceEpoch());
            query.exec();

            while (query.next()) {
                qint64 timestamp = query.value(0).toLongLong();
                double temperature = query.value(1).toDouble();
                QDateTime datetime;
                datetime.setMSecsSinceEpoch(timestamp);
                series->append(datetime.toMSecsSinceEpoch(), temperature);
            }
        });
    }
};

示例

下面以绘制线性函数为例,演示使用 Qt 连接 MySQL 数据库和展示历史数据的完整流程。

使用 MySQL 创建一个名为 test 的数据库,并在其中新建一个名为 line_data 的表,字段如下:

id x y
1 0 1
2 1 3
3 2 5
4 3 7
5 4 9

在 Qt 项目中创建一个 MainWindow 类,并添加上述代码。在 MainWindow::MainWindow() 中,使用以下代码连接数据库并查询数据:

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("test");
db.setUserName("root");
db.setPassword("password");

if (!db.open()) {
    qDebug() << "Failed to connect to database!";
    return;
}

QSqlQuery query;
query.exec("SELECT * FROM line_data");

QChart *chart = new QChart;
chart->setTitle("Line Data");

QLineSeries *series = new QLineSeries;

while (query.next()) {
    series->append(query.value("x").toDouble(), query.value("y").toDouble());
}

chart->addSeries(series);
chart->createDefaultAxes();
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);

QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
setCentralWidget(chartView);

编译运行项目,可以看到输出了包含数据的线性函数图表。

接下来我们继续演示如何查询并显示历史数据。在 MainWindow 界面构造函数中,将代码更改为:

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("test");
db.setUserName("root");
db.setPassword("password");

if (!db.open()) {
    qDebug() << "Failed to connect to database!";
    return;
}

QWidget *centralWidget = new QWidget;
setCentralWidget(centralWidget);

QGridLayout *layout = new QGridLayout(centralWidget);

QChartView *chartView = new QChartView(this);
chartView->setRenderHint(QPainter::Antialiasing);
layout->addWidget(chartView, 0, 1, 1, 1);

QDateTimeEdit *startTimeEdit = new QDateTimeEdit(this);
startTimeEdit->setDateTime(QDateTime::currentDateTime().addDays(-1));
startTimeEdit->setDisplayFormat("yyyy-MM-dd hh:mm:ss");
layout->addWidget(startTimeEdit, 1, 0, 1, 1);

QDateTimeEdit *endTimeEdit = new QDateTimeEdit(this);
endTimeEdit->setDateTime(QDateTime::currentDateTime());
endTimeEdit->setDisplayFormat("yyyy-MM-dd hh:mm:ss");
layout->addWidget(endTimeEdit, 1, 1, 1, 1);

QPushButton *searchButton = new QPushButton("Search");
layout->addWidget(searchButton, 1, 2, 1, 1);

QChart *chart = new QChart();
chart->setTitle("Line Data");
QLineSeries *series = new QLineSeries();
chart->addSeries(series);
chart->createDefaultAxes();
chartView->setChart(chart);

connect(searchButton, &QPushButton::clicked, [this, series, startTimeEdit, endTimeEdit]() {
    series->clear();

    QSqlQuery query;
    query.prepare("SELECT * FROM line_data WHERE x >= ? AND x <= ?");
    query.bindValue(0, startTimeEdit->dateTime().toMSecsSinceEpoch() / 1000);
    query.bindValue(1, endTimeEdit->dateTime().toMSecsSinceEpoch() / 1000);
    query.exec();

    while (query.next()) {
        series->append(query.value("x").toDouble(), query.value("y").toDouble());
    }
});

运行程序,可以看到主窗口中已经添加了 startDateEdit、endDateEdit 和 Button 控件,并且正确地绑定了按键事件。优化之后,我们可以筛选出上述表中的 x 在某个时间段内的数据,并绘制饼图。

以上就是 C/C++ Qt 数据库与Chart历史数据展示攻略的完整内容。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C/C++ Qt 数据库与Chart历史数据展示 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C 常量

    C常量的使用攻略 C常量是指在程序中不可修改的、固定的值。常量在程序中具有重要的作用,可以提高程序的可读性、可维护性,同时还能防止程序出现不必要的错误。C语言中定义常量的方式有两种:使用#define宏定义和使用const关键字定义。 使用#define宏定义常量 使用#define宏定义常量的格式如下: #define 常量名 常量值 常量名一般用大写字母…

    C 2023年5月10日
    00
  • 玩转宏定义——从入门到进阶

      宏定义是什么   宏定义(macro definition)是 C/C++ 中的一种预处理指令,可以在编译之前替换源代码中的一些文本。简单来说就是用宏自定义了一些其它符号,这些符号在使用时全等于被替换的内容。 #define  DATE    “2023_01_20” #define  FILE_NUM  250 上面两个例子中表现的就是宏定义的基本格式…

    C语言 2023年4月18日
    00
  • Python实现将字典内容写入json文件

    Python是一种非常强大的编程语言,也是一种非常受欢迎的数据处理工具。Python也是解析JSON格式数据的一种非常常用的方式。下面是“Python实现将字典内容写入JSON文件”的完整攻略: 第一步:导入json模块 Python支持读写JSON格式的数据,需要先导入json模块。在Python标准库中,json模块提供了两个方法load()和dump(…

    C 2023年5月23日
    00
  • 解析C#拼接Json串的几种方法

    解析C#拼接Json串的几种方法 在C#中解析Json串并将其转化为对象或者拼接Json字符串通常是非常有用的。以下是几种解析C#拼接Json串的方法。 1. 使用Newtonsoft.Json Newtonsoft.Json是.NET开发中最常用的序列化和反序列化库,它可以轻松地将对象转化为Json字符串。使用Newtonsoft.Json进行Json序列…

    C 2023年5月23日
    00
  • 深入理解C语言 static、extern与指针函数

    概述 在C语言中,static和extern是两个关键字,它们的作用主要与变量和函数的作用域和链接有关。而指针函数则是C语言中比较重要的一个概念,用于返回指针类型数据的函数。本文将从这三个方面进行详细讲解。 static关键字 static是一个非常常用的关键字,在C语言中主要有两个作用: 改变变量的作用域。当一个变量被定义为static时,它的作用域仅限于…

    C 2023年5月23日
    00
  • C语言 运算符优先级和关联性

    C语言 运算符优先级和关联性 在C语言中,运算符优先级和关联性是非常重要的概念,它们是决定表达式求值结果的关键因素。本篇文章将详细讲解C语言中运算符优先级和关联性的使用方法。 运算符优先级 运算符优先级决定了表达式中运算符的执行顺序,它们会影响表达式求值结果。C语言中,运算符优先级是按照固定的顺序进行计算。下表展示了C语言中一些常见运算符的优先级,从高到低。…

    C 2023年5月9日
    00
  • C++智能指针之shared_ptr详解

    C++智能指针之shared_ptr详解 什么是智能指针 智能指针是一种特殊类型的指针,它会自动管理指针所指向的内存,从而避免了因为内存管理不当而导致的内存泄露、多次释放等问题。C++11中提供了三种智能指针:unique_ptr、shared_ptr和weak_ptr。 shared_ptr的介绍 shared_ptr是一种智能指针,它可用于多个指针共享同…

    C 2023年5月23日
    00
  • C++实现二叉树基本操作详解

    C++实现二叉树基本操作详解 二叉树是计算机科学中的重要数据结构,其实现在C++编程中是必不可少的。本文将从二叉树的定义、基本操作的实现以及示例说明三个方面,详细讲解如何在C++中实现二叉树。 一、二叉树的定义 二叉树是一种树形结构,其中每个节点最多只包含两个子节点(左子节点和右子节点)。每个节点都包含一个值(或者说是一个数据项),而左右子节点则分别指向另外…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部