I have been reading a lot about this, but I don't fully get how to go about it (eg see How to avoid Qt app.exec() blocking main thread ).
The following code is a very naievely written minimal example of what I'm trying to achieve. For the sake of this example: there is a terminal in which you put exam grades for the same subject for one student. Concretely: how a student did for his/her English course over the whole year. Every time you put in the grade of a student, a Qt chart updates and shows the progression.
This is the code I wrote:
#include <iostream>
#include <vector>
#include <QApplication>
#include <QMainWindow>
#include <QChartView>
#include <QLineSeries>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
std::vector<int> examScores;
int totalExams = 5;
QtCharts::QLineSeries *series = new QtCharts::QLineSeries();
QtCharts::QChart *chart = new QtCharts::QChart();
chart->legend()->hide();
chart->createDefaultAxes();
QtCharts::QChartView *chartView = new QtCharts::QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(400, 300);
for (int i = 1; i <= totalExams; i++)
{
std::cout << "Enter score of exam " << i << " ";
std::string userInput;
getline(std::cin, userInput);
int score = std::stoi(userInput);
examScores.push_back(score);
series->append(i, score);
chart->addSeries(series);
window.show();
app.exec();
chart->removeSeries(series);
}
return 0;
}
Now, there are many issues here from a software engineering perspective (eg not sanitizing input, and so on), but what I can't wrap my head around is how to rewrite app.exec();
. I know it shouldn't be there, since it's blocking, and I know Qt isn't meant to be written this way.
So I'm wondering: how would you rewrite this example in order to make app.exec();
non-blocking and allow the program to receive user input on the terminal at all times?
This is how I put it into its own thread while still being able to handle CLI input. A lot of things are still wrong with this code from a code review perspective, but the basic functionality (putting it into a different thread) works.
#include <iostream>
#include <vector>
#include <thread>
#include <QApplication>
#include <QMainWindow>
#include <QChartView>
#include <QLineSeries>
std::vector<int> examScores;
void pollForUserInput(QtCharts::QLineSeries *series, int totalExams)
{
for (int i = 1; i <= totalExams; i++)
{
std::cout << "\nEnter score of exam " << i << " " << std::endl;
std::string userInput;
getline(std::cin, userInput);
int score = std::stoi(userInput);
examScores.push_back(score);
series->append(i, score);
}
std::cout << "done" << std::endl;
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QtCharts::QLineSeries *series = new QtCharts::QLineSeries();
int totalExams = 5;
std::thread t1(pollForUserInput, series, totalExams);
QtCharts::QChart *chart = new QtCharts::QChart();
chart->legend()->hide();
chart->addSeries(series);
chart->createDefaultAxes();
chart->axisX()->setRange(1, totalExams); // see https://stackoverflow.com/questions/38804179/how-to-repaint-a-qchart
chart->axisY()->setRange(1, 10); // see https://stackoverflow.com/questions/38804179/how-to-repaint-a-qchart
QtCharts::QChartView *chartView = new QtCharts::QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(400, 300);
window.show();
return app.exec();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.