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

yizhihongxing

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日

相关文章

  • vscode配置远程开发环境并远程调试运行C++代码的教程

    下面我将为您详细讲解如何使用 VSCode 配置远程开发环境并远程调试运行 C++ 代码。 准备工作 在开始之前,我们需要准备以下工具和环境: VSCode Remote Development 插件 SSH 客户端程序 远程服务器 其中,Remote Development 是一个专门提供远程开发功能的 VSCode 插件,它可以让我们在本地使用 VSCo…

    C 2023年5月23日
    00
  • C++执行shell命令的多种实现方法

    C++可以通过多种方式执行shell命令,以下是其中的一些常见方法。 使用system函数 system函数是最简单和常见的执行shell命令的方法,可以通过将命令字符串作为参数传递给system函数来执行命令。例如,以下代码将显示当前目录中的所有文件列表: #include <cstdlib> int main() { system(&quot…

    C 2023年5月23日
    00
  • 全境封锁2武器有哪些 全武器介绍

    全境封锁2武器有哪些 全武器介绍 全境封锁2是一款以军事背景为主题的 RPG 游戏,其中武器种类丰富。本文将对这些武器进行全面介绍。 武器种类 全境封锁2中的武器大致可分为以下几类: 步枪 冲锋枪 狙击枪 轻机枪 战斗霰弹枪 手枪 火焰喷射器 黄金枪 不同武器介绍 步枪 步枪是一类长枪,常见的有 AK47、M16A2 等。通常适用于中远距离作战,威力较大,但…

    C 2023年5月22日
    00
  • C语言容易被忽视的函数设计原则基础

    我来详细讲解一下“C语言容易被忽视的函数设计原则基础”的攻略。 1. 函数设计原则的重要性 函数是程序中最重要的组成部分之一,良好设计的函数可以增强程序的可读性、可维护性、可扩展性和可重用性。函数设计原则是编写好函数的基础,而忽视这些基本的原则将会导致程序出现各种问题。编写出符合基本原则的函数,既能使程序更加健壮、高效,又能提高程序的可维护性和可读性。 2.…

    C 2023年5月23日
    00
  • C++基类指针和派生类指针之间的转换方法讲解

    C++基类指针和派生类指针之间的转换方法讲解 在C++多态编程中,我们经常需要将一个基类指针转换为派生类指针或将一个派生类指针转换为基类指针。这种指针之间的转换是很常见的操作,也十分重要,本文将详细介绍这种指针之间的转换方法。 基类指针转化为派生类指针 在C++中,基类指针转化为派生类指针有两种方法:静态转换和动态转换。 1. 静态转换 静态转换可以将基类指…

    C 2023年5月22日
    00
  • C语言之详解静态变量static

    C语言之详解静态变量static 在C语言中,关键字static可以用于修饰全局变量,局部变量和函数,其作用分别如下: 1. 修饰全局变量 在全局变量前加上static关键字,表示该变量具有静态存储期和静态链接属性。 在同一文件中的其他函数中不能访问该变量。 只能被定义变量的函数访问。 被初始化为0,除非在定义时显式初始化。 static int a; //…

    C 2023年5月24日
    00
  • golang struct json tag的使用以及深入讲解

    让我来详细讲解一下 “golang struct json tag的使用以及深入讲解” 的攻略。 1. 什么是 struct json tag? golang中,可以在一个 struct 中通过添加 json tag,来指定如何将 struct 转换为 JSON 格式(序列化)或将 JSON 数据转换为 struct(反序列化)。在 JSON Tag 中,一…

    C 2023年5月23日
    00
  • JSON对象 详解及实例代码

    JSON对象详解及实例代码 什么是JSON对象? JSON(JavaScript Object Notation)是一种基于文本的轻量级数据交换格式,易于阅读和编写,也易于机器解析和生成。它的基本数据结构包括对象和数组,由键值对和列表组成,支持数字、字符串、布尔值、以及 null 和另一个 JSON对象或数组等基本数据类型。 如何创建JSON对象? 1. 直…

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