C/C++ Qt 数据库与Chart历史数据展示攻略
介绍
Qt 是一款跨平台的GUI应用开发框架,它有很多成熟的库和工具,同时也提供了对数据库和数据可视化的支持。这里将介绍如何使用 C++ Qt 开发一个历史数据展示的程序。主要涉及到以下三个方面:
- 数据库连接与操作
- 数据可视化 (Chart)
- 图形界面设计 (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 工具创建历史数据展示程序的界面的步骤:
- 打开 Designer 工具,并新建一个空白窗口。
- 在 “Widget Box” 中选择 QChartView、QDateTimeEdit 和 QPushButton,并拖拽到窗口中。
- 调整上述组件的大小和位置,使其符合需求。
- 在界面右键,选择“Layoout”->“Lay Out in a Grid”,实现组件的网格布局。
- 在 “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技术站