The Qt charting module is unresponsive
-
qt charts module, adding data through QLineSeries is not reflected, and I have added QLineSeries to the chart, adding static data is also possible, but the dynamic will not respond.
This is my chart data insertion functionvoid hum_wdiget::syn_hum_charts() { qDebug() << "syn_hum_charts called with hum = " << hum; second++; int humidity = hum; qDebug() << "humidity =" << humidity; series_hum->append(second, humidity); chart_hum->update(); view_hum->repaint(); //Manually trigger a chart redraw axis_hum->setRange(second - 10, second + 10); // Let's say we want to display data from the last 10 seconds // Force processing of unprocessed events to help ensure that the view is updated in a timely manner QCoreApplication::processEvents(); update(); }
Here are the test results of my running function, which means that the function is working properly
syn_hum_charts called with hum = 52
humidity = 52
But nothing has changed in the chart
So I tested it and inserted it statically at creation timeseries_hum->append(1, 20); series_hum->append(2, 30); series_hum->append(3, 40); series_hum->append(5, 20); series_hum->append(6, 20);
The insertion was found to be successful
After that, I tested the function directly with a timer, and the Debug test data result and the above result have been the same, but the inserted data is always the x-axis is second, and the y-axis humidity = hum is the defined value of humconnect(timer, &QTimer::timeout, this, &hum_wdiget::syn_hum_charts);
-
@JonB Hi, thank you very much for your reply and reminder, I apologize for my previous ignorance behavior, but the reason is because I found that my issue was miscategorized, so I want to delete the previous post and resend it. I listened to you and have already made a minimal case.
Header file
charts_data.h#ifndef CHARTS_DAT[link text]A_H #define CHARTS_DATA_H #include <QWidget> #include <QtCharts> #include <QDebug> using namespace QtCharts; namespace Ui { class charts_data; } class charts_data : public QWidget { Q_OBJECT public: explicit charts_data(QWidget *parent = nullptr); ~charts_data(); //initialize void charts_init(); //Set up the receive function void receive_function(int d_received); //Chart updates void charts_update_function(); void create_charts(); private: int second; //Data received int data_received; //chart subassembly QChart* chart_data; QLineSeries* series_data; QChartView* view_data; QValueAxis* axis_data_x; QValueAxis* axis_data_y; QVBoxLayout* vbox_data; private: Ui::charts_data *ui; }; #endif // CHARTS_DATA_H
data.h
#ifndef DATA_H #define DATA_H #include <QWidget> #include <charts_data.h> #include <QTime> QT_BEGIN_NAMESPACE namespace Ui { class data; } QT_END_NAMESPACE class data : public QWidget { Q_OBJECT public: data(QWidget *parent = nullptr); ~data(); //initialize void data_init(); private: charts_data* c_data; int test_data; QTimer* timer; private slots: //Transfer the data to the chart file void Transfer_data(); private: Ui::data *ui; }; #endif // DATA_H
Source files
charts_data.cpp#include "charts_data.h" #include "ui_charts_data.h" charts_data::charts_data(QWidget *parent) : QWidget(parent), ui(new Ui::charts_data) { ui->setupUi(this); charts_init(); create_charts(); } charts_data::~charts_data() { delete ui; } void charts_data::charts_init() { second = 0; chart_data = new QChart; series_data = new QLineSeries; view_data = new QChartView; axis_data_x = new QValueAxis; axis_data_y = new QValueAxis; vbox_data = new QVBoxLayout; } void charts_data::receive_function(int d_received) { data_received = d_received; charts_update_function(); } void charts_data::charts_update_function() { qDebug() << data_received; second++; series_data->append(second,data_received); } void charts_data::create_charts() { //Set the polyline series_data->setName("湿度"); series_data->setPointLabelsVisible(true); series_data->setPointsVisible(true); series_data->setPointLabelsFormat("@yPoint"); series_data->append(1, 20); series_data->append(2, 30); series_data->append(3, 40); series_data->append(5, 20); series_data->append(6, 20); //Set the axes axis_data_x->setRange(0, 10); axis_data_x->setTitleText("time(s)"); axis_data_y->setRange(0, 100); axis_data_y->setTitleText("data(%)"); //Create a table chart_data= new QChart(); chart_data->setTitle("Humidity polyline"); chart_data->addAxis(axis_data_x,Qt::AlignBottom); chart_data->addAxis(axis_data_y, Qt::AlignLeft); chart_data->setMargins(QMargins(10, 10, 10, 10)); chart_data->createDefaultAxes(); chart_data->legend()->setVisible(true); chart_data->addSeries(series_data); //The sequence is added to the axes series_data->attachAxis(axis_data_x); series_data->attachAxis(axis_data_y); //Set the view view_data->setChart(chart_data); view_data->setRenderHint(QPainter::Antialiasing); // Add a view to the layout) vbox_data->addWidget(view_data); setLayout(vbox_data); // Resize the view to fit its contents view_data->fitInView(chart_data->plotArea(), Qt::KeepAspectRatio); }
data.cpp
#include "data.h" #include "ui_data.h" data::data(QWidget *parent) : QWidget(parent) , ui(new Ui::data) { ui->setupUi(this); data_init(); //The timer transmits data every second, which triggers the chart file to update the chart connect(timer, &QTimer::timeout, this, &data::Transfer_data); timer->start(1000); } data::~data() { delete ui; } void data::data_init() { test_data = 0; c_data = new charts_data(); timer = new QTimer; } void data::Transfer_data() { test_data++; c_data->receive_function(test_data); }
main.cpp
#include "data.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); data w; w.show(); return a.exec(); }
Interface files
charts_data.ui<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>charts_data</class> <widget class="QWidget" name="charts_data"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>400</width> <height>300</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> </widget> <resources/> <connections/> </ui>
data.ui
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>data</class> <widget class="QWidget" name="data"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>600</height> </rect> </property> <property name="windowTitle"> <string>data</string> </property> <widget class="charts_data" name="widget" native="true"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>801</width> <height>601</height> </rect> </property> </widget> </widget> <customwidgets> <customwidget> <class>charts_data</class> <extends>QWidget</extends> <header>charts_data.h</header> <container>1</container> </customwidget> </customwidgets> <resources/> <connections/> </ui>
QT += core gui charts greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++17 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ charts_data.cpp \ main.cpp \ data.cpp HEADERS += \ charts_data.h \ data.h FORMS += \ charts_data.ui \ data.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
-
@baizhou
This is awfully far from being a minimal example.... Can't you just get rid of 90% of your convoluted code and try adding a few new points to a line series on a timer?I note that you create two
new QChart
s, one incharts_init()
another increate_charts()
. I'm not going to figure the consequence of that.I also believe you create a "static" point (as you call it) like
series_data->append(1, 20);
, and then if you work through your code I think you create a new "dynamic" point (as you call it) also atseries_data->append(1, ...)
becausesecond
counts again from 0? In which case, you now have multiple points atx==1
so how do you know the new, second point has not been created?If I were you I would simplify your code to a minimal example and check behaviour.
-
@JonB Hello, according to your suggestion, I have located the problem I am in from a small program just now and has changed it successfully, thank you very much for your suggestion to me, and also let me learn a new way to solve the problem. However, I am vague about the specifications of a minimal case, and I have minimized my question as much as possible, and I may also ask my questions in the future, and I will go to other questions to learn.
-
@baizhou said in The Qt charting module is unresponsive:
Hello, according to your suggestion, I have located the problem I am in from a small program just now and has changed it successfully
And what did you change/why is it successful now? It helps if you tell us :) Was it that the new points were being added, but because you were re-using the same x-coordinate as an existing point you just did not see it?
-
@JonB I minimized the issue and rediscovered that the reason why I wasn't showing updates to the data was because my charts belonged to different objects
hum_wdiget * H_wdiget;
I define an object pointer so that the data passed through the object pointer belongs only to that object.
So, I commented out the code that created the view in the diagram file and added it to the layout
hum_wdiget.cppvoid hum_wdiget::create_hum_charts() { ...other code... // vbox_hum->addWidget(view_hum); // setLayout(vbox_hum); }
After that, I created the chart in the main interface directly from the object, and added the following paragraph.
widget.cppWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); ...ohter code... vbox_hum = new QVBoxLayout(); vbox_hum->addWidget(H_wdiget->view_hum); setLayout(vbox_hum); }
-