问题
I want to create two subplots (like 2 rows), the first plot will show the line series graph based on Analog to Digital Converter counts stored in a text file and the second plot will show the line series graph based on Temperature values stored in a text file. I am able to plot the line series in the same plot, but I want to plot it in two separate subplots.
#include <QApplication>
#include <QMainWindow>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QTime>
#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
#include <QDateTimeAxis>
#include <QValueAxis>
#include <QDebug>
QT_CHARTS_USE_NAMESPACE
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Open File
QFile file("D:\\Projects\\Embedded\\ArduinoTempLogger\\01-21-18.txt");
if( !file.open(QIODevice::ReadOnly|QIODevice::Text) )
{
qDebug() << "File don't exist";
return 1;
}
QTextStream stream(&file);
QLineSeries *adc_series = new QLineSeries();
QLineSeries *temp_series = new QLineSeries();
QDateTime datetime = QDateTime::currentDateTime();
while( !stream.atEnd() )
{
QString line = stream.readLine();
QStringList values = line.split(",");
QTime time;
time = QTime::fromString(values[0], "hh:mm:ss");
datetime.setTime(time);
adc_series->append( datetime.toMSecsSinceEpoch(), values[1].toUInt() );
temp_series->append( datetime.toMSecsSinceEpoch(), values[2].toDouble() );
// qDebug() << time.toString("hh:mm:ss") << "-->" << datetime.toMSecsSinceEpoch();
}
file.close();
QChart *chart = new QChart();
chart->legend()->hide();
chart->addSeries(adc_series);
chart->addSeries(temp_series);
// chart->createDefaultAxes();
chart->setTitle("Temperature Plot");
// Since we use QLineSeries, calling createDefaultAxes will create QValueAxis both as X and Y axis.
// To use QDateTimeAxis we need to set it manually to the chart.
// First, the instance of QDateTimeAxis is created, then the number of ticks to be shown is set.
//
QDateTimeAxis *axisX = new QDateTimeAxis;
axisX->setTickCount(10);
axisX->setFormat("hh:mm:ss");
axisX->setTitleText("Time Axis");
chart->addAxis(axisX, Qt::AlignBottom);
adc_series->attachAxis(axisX);
temp_series->attachAxis(axisX);
QValueAxis *axisY = new QValueAxis;
axisY->setLabelFormat("%i");
axisY->setTitleText("Temperature and ADC Value");
axisY->setRange(0, 100);
chart->addAxis(axisY, Qt::AlignLeft);
adc_series->attachAxis(axisY);
temp_series->attachAxis(axisY);
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(820, 600);
window.show();
return a.exec();
}
The data which I am reading from the file is in the following format.
16:08:45,50,24.4
16:08:46,47,22.9
16:08:47,60,29.3
16:08:48,45,22
16:08:49,49,23.9
16:08:50,54,26.4
16:08:51,46,22.5
16:08:52,40,19.5
16:08:53,50,24.4
16:08:54,50,24.4
16:08:55,50,24.4
16:08:56,59,28.8
16:08:57,49,23.9
16:08:58,62,30.3
16:08:59,58,28.3
16:09:00,47,22.9
16:09:01,54,26.4
16:09:02,61,29.8
16:09:03,47,22.9
16:09:04,50,24.4
16:09:05,55,26.9
16:09:06,46,22.5
16:09:07,60,29.3
16:09:08,49,23.9
16:09:09,57,27.8
16:09:10,42,20.5
16:09:11,49,23.9
16:09:12,56,27.3
16:09:13,64,31.3
16:09:14,51,24.9
16:09:15,53,25.9
16:09:16,57,27.8
I am using Qt 5.14.1 on Windows 10 Can someone please guide me achieving in this? Thanks in advance.
回答1:
There is no direct solution provided by Qt, so there are several alternatives:
- Create 2 QChartView and place them inside a QVBoxLayout.
- Create 2 QChart and place them inside a QChartView using a QGraphicsLinearLayout.
The first method is trivial so I will not show an example, however if I show the code of the second method:
#include <QtWidgets>
#include <QtCharts>
QT_CHARTS_USE_NAMESPACE
class GraphicsView: public QGraphicsView{
public:
GraphicsView(QWidget *parent=nullptr):QGraphicsView(parent){
setScene(new QGraphicsScene);
layout = new QGraphicsLinearLayout(Qt::Vertical);
form = new QGraphicsWidget;
form->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
form->setLayout(layout);
scene()->addItem(form);
layout->setSpacing(0);
}
void addChart(QChart *chart){
if(chart){
layout->addItem(chart);
}
}
protected:
void resizeEvent(QResizeEvent *event){
if(scene())
scene()->setSceneRect(QRect(QPoint(0, 0), event->size()));
if(form)
form->resize(event->size());
QGraphicsView::resizeEvent(event);
}
private:
QGraphicsWidget *form;
QGraphicsLinearLayout *layout;
};
static bool create_series(QLineSeries *adc_series, QLineSeries *temp_series){
QFile file("D:\\Projects\\Embedded\\ArduinoTempLogger\\01-21-18.txt");
if( !file.open(QIODevice::ReadOnly|QIODevice::Text)){
qDebug() << "File don't exist";
return false;
}
QTextStream stream(&file);
QDateTime datetime = QDateTime::currentDateTime();
while( !stream.atEnd()){
QString line = stream.readLine();
QStringList values = line.split(",");
datetime.setTime(QTime::fromString(values[0], "hh:mm:ss"));
adc_series->append( datetime.toMSecsSinceEpoch(), values[1].toUInt() );
temp_series->append( datetime.toMSecsSinceEpoch(), values[2].toDouble() );
}
file.close();
return true;
}
static QChart* create_chart(const QString & title, QLineSeries *series){
QChart * chart = new QChart;
chart->legend()->hide();
chart->addSeries(series);
QDateTimeAxis *axisX = new QDateTimeAxis;
axisX->setTickCount(10);
axisX->setFormat("hh:mm:ss");
axisX->setTitleText("Time Axis");
chart->addAxis(axisX, Qt::AlignBottom);
series->attachAxis(axisX);
QValueAxis *adc_axisY = new QValueAxis;
adc_axisY->setLabelFormat("%i");
adc_axisY->setTitleText(title);
adc_axisY->setRange(0, 100);
chart->addAxis(adc_axisY, Qt::AlignLeft);
series->attachAxis(adc_axisY);
return chart;
}
int main(int argc, char *argv[]){
QApplication a(argc, argv);
QLineSeries *adc_series = new QLineSeries;
QLineSeries *temp_series = new QLineSeries;
if(!create_series(adc_series, temp_series))
return -1;
GraphicsView view;
view.addChart(create_chart("ADC Value", adc_series));
view.addChart(create_chart("Temperature Value", temp_series));
view.show();
view.resize(640, 480);
return a.exec();
}
On the other hand, Qt has not given much love to Qt Charts, so simple tasks such as subplots do not exist, so I recommend using other libraries such as QCustomPlot that do offer that functionality, in this link there is an example.
来源:https://stackoverflow.com/questions/60534586/how-to-create-subplot-using-qcharts