Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
247 views
in Technique[技术] by (71.8m points)

c++ - Qt on Mac: app.exec() blocks terminal input, how to rewrite this minimal example?

I have been reading a lot about this, but I don't fully get how to go about it (e.g. 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 (e.g. 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?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 << "
Enter 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();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...